home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / gas / obj-form.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-17  |  95.7 KB  |  3,842 lines

  1. /* coff object file format
  2.    Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994
  3.    Free Software Foundation, Inc.
  4.  
  5.    This file is part of GAS.
  6.  
  7.    GAS is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2, or (at your option)
  10.    any later version.
  11.  
  12.    GAS is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with GAS; see the file COPYING.  If not, write to
  19.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "as.h"
  22. #include "obstack.h"
  23. #include "subsegs.h"
  24.  
  25. const char *s_get_name PARAMS ((symbolS * s));
  26. static symbolS *def_symbol_in_progress;
  27.  
  28.  
  29. /* stack stuff */
  30. typedef struct
  31.   {
  32.     unsigned long chunk_size;
  33.     unsigned long element_size;
  34.     unsigned long size;
  35.     char *data;
  36.     unsigned long pointer;
  37.   }
  38. stack;
  39.  
  40. static stack *
  41. stack_init (chunk_size, element_size)
  42.      unsigned long chunk_size;
  43.      unsigned long element_size;
  44. {
  45.   stack *st;
  46.  
  47.   st = (stack *) malloc (sizeof (stack));
  48.   if (!st)
  49.     return 0;
  50.   st->data = malloc (chunk_size);
  51.   if (!st->data)
  52.     {
  53.       free (st);
  54.       return 0;
  55.     }
  56.   st->pointer = 0;
  57.   st->size = chunk_size;
  58.   st->chunk_size = chunk_size;
  59.   st->element_size = element_size;
  60.   return st;
  61. }
  62.  
  63. #if 0
  64. /* Not currently used.  */
  65. static void
  66. stack_delete (st)
  67.      stack *st;
  68. {
  69.   free (st->data);
  70.   free (st);
  71. }
  72. #endif
  73.  
  74. static char *
  75. stack_push (st, element)
  76.      stack *st;
  77.      char *element;
  78. {
  79.   if (st->pointer + st->element_size >= st->size)
  80.     {
  81.       st->size += st->chunk_size;
  82.       if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
  83.     return (char *) 0;
  84.     }
  85.   memcpy (st->data + st->pointer, element, st->element_size);
  86.   st->pointer += st->element_size;
  87.   return st->data + st->pointer;
  88. }
  89.  
  90. static char *
  91. stack_pop (st)
  92.      stack *st;
  93. {
  94.   if (st->pointer < st->element_size)
  95.     {
  96.       st->pointer = 0;
  97.       return (char *) 0;
  98.     }
  99.   st->pointer -= st->element_size;
  100.   return st->data + st->pointer;
  101. }
  102.  
  103. /*
  104.  * Maintain a list of the tagnames of the structres.
  105.  */
  106.  
  107. static struct hash_control *tag_hash;
  108.  
  109. static void
  110. tag_init ()
  111. {
  112.   tag_hash = hash_new ();
  113. }
  114.  
  115. static void
  116. tag_insert (name, symbolP)
  117.      const char *name;
  118.      symbolS *symbolP;
  119. {
  120.   const char *error_string;
  121.  
  122.   if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
  123.     {
  124.       as_fatal ("Inserting \"%s\" into structure table failed: %s",
  125.         name, error_string);
  126.     }
  127. }
  128.  
  129. static symbolS *
  130. tag_find (name)
  131.      char *name;
  132. {
  133. #ifdef STRIP_UNDERSCORE
  134.   if (*name == '_')
  135.     name++;
  136. #endif /* STRIP_UNDERSCORE */
  137.   return (symbolS *) hash_find (tag_hash, name);
  138. }
  139.  
  140. static symbolS *
  141. tag_find_or_make (name)
  142.      char *name;
  143. {
  144.   symbolS *symbolP;
  145.  
  146.   if ((symbolP = tag_find (name)) == NULL)
  147.     {
  148.       symbolP = symbol_new (name, undefined_section,
  149.                 0, &zero_address_frag);
  150.  
  151.       tag_insert (S_GET_NAME (symbolP), symbolP);
  152. #ifdef BFD_ASSEMBLER
  153.       symbol_table_insert (symbolP);
  154. #endif
  155.     }                /* not found */
  156.  
  157.   return symbolP;
  158. }
  159.  
  160.  
  161.  
  162. #ifdef BFD_ASSEMBLER
  163.  
  164. static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
  165.  
  166. #define GET_FILENAME_STRING(X) \
  167. ((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
  168.  
  169. /* @@ Ick.  */
  170. static segT
  171. fetch_coff_debug_section ()
  172. {
  173.   static segT debug_section;
  174.   if (!debug_section)
  175.     {
  176.       CONST asymbol *s;
  177.       s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0);
  178.       assert (s != 0);
  179.       debug_section = s->section;
  180.     }
  181.   return debug_section;
  182. }
  183.  
  184. void
  185. SA_SET_SYM_ENDNDX (sym, val)
  186.      symbolS *sym;
  187.      symbolS *val;
  188. {
  189.   combined_entry_type *entry, *p;
  190.  
  191.   entry = &coffsymbol (sym->bsym)->native[1];
  192.   p = coffsymbol (val->bsym)->native;
  193.   entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
  194.   entry->fix_end = 1;
  195. }
  196.  
  197. static void
  198. SA_SET_SYM_TAGNDX (sym, val)
  199.      symbolS *sym;
  200.      symbolS *val;
  201. {
  202.   combined_entry_type *entry, *p;
  203.  
  204.   entry = &coffsymbol (sym->bsym)->native[1];
  205.   p = coffsymbol (val->bsym)->native;
  206.   entry->u.auxent.x_sym.x_tagndx.p = p;
  207.   entry->fix_tag = 1;
  208. }
  209.  
  210. static int
  211. S_GET_DATA_TYPE (sym)
  212.      symbolS *sym;
  213. {
  214.   return coffsymbol (sym->bsym)->native->u.syment.n_type;
  215. }
  216.  
  217. int
  218. S_SET_DATA_TYPE (sym, val)
  219.      symbolS *sym;
  220.      int val;
  221. {
  222.   coffsymbol (sym->bsym)->native->u.syment.n_type = val;
  223.   return val;
  224. }
  225.  
  226. int
  227. S_GET_STORAGE_CLASS (sym)
  228.      symbolS *sym;
  229. {
  230.   return coffsymbol (sym->bsym)->native->u.syment.n_sclass;
  231. }
  232.  
  233. int
  234. S_SET_STORAGE_CLASS (sym, val)
  235.      symbolS *sym;
  236.      int val;
  237. {
  238.   coffsymbol (sym->bsym)->native->u.syment.n_sclass = val;
  239.   return val;
  240. }
  241.  
  242. /* Merge a debug symbol containing debug information into a normal symbol. */
  243.  
  244. void
  245. c_symbol_merge (debug, normal)
  246.      symbolS *debug;
  247.      symbolS *normal;
  248. {
  249.   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
  250.   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
  251.  
  252.   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
  253.     /* take the most we have */
  254.     S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
  255.  
  256.   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
  257.     {
  258.       /* Move all the auxiliary information.  */
  259.       /* @@ How many fields do we want to preserve?  Would it make more
  260.      sense to pick and choose those we want to copy?  Should look
  261.      into this further....  [raeburn:19920512.2209EST]  */
  262.       alent *linenos;
  263.       linenos = coffsymbol (normal->bsym)->lineno;
  264.       memcpy ((char *) &coffsymbol (normal->bsym)->native,
  265.           (char *) &coffsymbol (debug->bsym)->native,
  266.           S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
  267.       coffsymbol (normal->bsym)->lineno = linenos;
  268.     }
  269.  
  270.   /* Move the debug flags. */
  271.   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
  272. }
  273.  
  274. static symbolS *previous_file_symbol;
  275. void
  276. c_dot_file_symbol (filename)
  277.      char *filename;
  278. {
  279.   symbolS *symbolP;
  280.  
  281.   symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
  282.  
  283.   S_SET_STORAGE_CLASS (symbolP, C_FILE);
  284.   S_SET_NUMBER_AUXILIARY (symbolP, 1);
  285.  
  286.   symbolP->bsym->flags = BSF_DEBUGGING;
  287.  
  288. #ifndef NO_LISTING
  289.   {
  290.     extern int listing;
  291.     if (listing)
  292.       {
  293.     listing_source_file (filename);
  294.       }
  295.   }
  296. #endif
  297.  
  298.   S_SET_VALUE (symbolP, (long) previous_file_symbol);
  299.  
  300.   previous_file_symbol = symbolP;
  301.  
  302.   /* Make sure that the symbol is first on the symbol chain */
  303.   if (symbol_rootP != symbolP)
  304.     {
  305.       if (symbolP == symbol_lastP)
  306.     {
  307.       symbol_lastP = symbol_lastP->sy_previous;
  308.     }            /* if it was the last thing on the list */
  309.  
  310.       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  311.       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
  312.       symbol_rootP = symbolP;
  313.     }                /* if not first on the list */
  314. }
  315.  
  316. /*
  317.  * Build a 'section static' symbol.
  318.  */
  319.  
  320. char *
  321. c_section_symbol (name, value, length, nreloc, nlnno)
  322.      char *name;
  323.      long value;
  324.      long length;
  325.      unsigned short nreloc;
  326.      unsigned short nlnno;
  327. {
  328.   symbolS *symbolP;
  329.  
  330.   symbolP = symbol_new (name,
  331.             (name[1] == 't'
  332.              ? text_section
  333.              : name[1] == 'd'
  334.              ? data_section
  335.              : bss_section),
  336.             value,
  337.             &zero_address_frag);
  338.  
  339.   S_SET_STORAGE_CLASS (symbolP, C_STAT);
  340.   S_SET_NUMBER_AUXILIARY (symbolP, 1);
  341.  
  342.   SA_SET_SCN_SCNLEN (symbolP, length);
  343.   SA_SET_SCN_NRELOC (symbolP, nreloc);
  344.   SA_SET_SCN_NLINNO (symbolP, nlnno);
  345.  
  346.   SF_SET_STATICS (symbolP);
  347.  
  348.   return (char *) symbolP;
  349. }
  350.  
  351. /* Line number handling */
  352.  
  353. struct line_no {
  354.   struct line_no *next;
  355.   fragS *frag;
  356.   alent l;
  357. };
  358.  
  359. int coff_line_base;
  360.  
  361. /* Symbol of last function, which we should hang line#s off of.  */
  362. static symbolS *line_fsym;
  363.  
  364. #define in_function()        (line_fsym != 0)
  365. #define clear_function()    (line_fsym = 0)
  366. #define set_function(F)        (line_fsym = (F), coff_add_linesym (F))
  367.  
  368.  
  369. void
  370. obj_symbol_new_hook (symbolP)
  371.      symbolS *symbolP;
  372. {
  373.   char underscore = 0;        /* Symbol has leading _ */
  374.  
  375.   {
  376.     long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
  377.     char *s = (char *) bfd_alloc_by_size_t (stdoutput, sz);
  378.     memset (s, 0, sz);
  379.     coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s;
  380.   }
  381.   S_SET_DATA_TYPE (symbolP, T_NULL);
  382.   S_SET_STORAGE_CLASS (symbolP, 0);
  383.   S_SET_NUMBER_AUXILIARY (symbolP, 0);
  384.  
  385.   if (S_IS_STRING (symbolP))
  386.     SF_SET_STRING (symbolP);
  387.   if (!underscore && S_IS_LOCAL (symbolP))
  388.     SF_SET_LOCAL (symbolP);
  389. }
  390.  
  391.  
  392. /*
  393.  * Handle .ln directives.
  394.  */
  395.  
  396. static symbolS *current_lineno_sym;
  397. static struct line_no *line_nos;
  398. /* @@ Blindly assume all .ln directives will be in the .text section...  */
  399. static int n_line_nos;
  400.  
  401. static void
  402. add_lineno (frag, offset, num)
  403.      fragS *frag;
  404.      int offset;
  405.      int num;
  406. {
  407.   struct line_no *new_line = (struct line_no *) bfd_alloc_by_size_t (stdoutput,
  408.                                      sizeof (struct line_no));
  409.   if (!current_lineno_sym)
  410.     {
  411.       abort ();
  412.     }
  413.   new_line->next = line_nos;
  414.   new_line->frag = frag;
  415.   new_line->l.line_number = num;
  416.   new_line->l.u.offset = offset;
  417.   line_nos = new_line;
  418.   n_line_nos++;
  419. }
  420.  
  421. void
  422. coff_add_linesym (sym)
  423.      symbolS *sym;
  424. {
  425.   if (line_nos)
  426.     {
  427.       coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos;
  428.       n_line_nos++;
  429.       line_nos = 0;
  430.     }
  431.   current_lineno_sym = sym;
  432. }
  433.  
  434. static void
  435. obj_coff_ln (appline)
  436.      int appline;
  437. {
  438.   int l;
  439.  
  440.   if (! appline && def_symbol_in_progress != NULL)
  441.     {
  442.       as_warn (".ln pseudo-op inside .def/.endef: ignored.");
  443.       demand_empty_rest_of_line ();
  444.       return;
  445.     }
  446.  
  447.   l = get_absolute_expression ();
  448.   if (!appline)
  449.     {
  450.       add_lineno (frag_now, frag_now_fix (), l);
  451.     }
  452.  
  453. #ifndef NO_LISTING
  454.   {
  455.     extern int listing;
  456.  
  457.     if (listing)
  458.       {
  459.     if (! appline)
  460.       l += coff_line_base - 1;
  461.     listing_source_line (l);
  462.       }
  463.   }
  464. #endif
  465.  
  466.   demand_empty_rest_of_line ();
  467. }
  468.  
  469. /*
  470.  *            def()
  471.  *
  472.  * Handle .def directives.
  473.  *
  474.  * One might ask : why can't we symbol_new if the symbol does not
  475.  * already exist and fill it with debug information.  Because of
  476.  * the C_EFCN special symbol. It would clobber the value of the
  477.  * function symbol before we have a chance to notice that it is
  478.  * a C_EFCN. And a second reason is that the code is more clear this
  479.  * way. (at least I think it is :-).
  480.  *
  481.  */
  482.  
  483. #define SKIP_SEMI_COLON()    while (*input_line_pointer++ != ';')
  484. #define SKIP_WHITESPACES()    while (*input_line_pointer == ' ' || \
  485.                        *input_line_pointer == '\t') \
  486.     input_line_pointer++;
  487.  
  488. static void
  489. obj_coff_def (what)
  490.      int what;
  491. {
  492.   char name_end;        /* Char after the end of name */
  493.   char *symbol_name;        /* Name of the debug symbol */
  494.   char *symbol_name_copy;    /* Temporary copy of the name */
  495.   unsigned int symbol_name_length;
  496.  
  497.   if (def_symbol_in_progress != NULL)
  498.     {
  499.       as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
  500.       demand_empty_rest_of_line ();
  501.       return;
  502.     }                /* if not inside .def/.endef */
  503.  
  504.   SKIP_WHITESPACES ();
  505.  
  506.   symbol_name = input_line_pointer;
  507. #ifdef STRIP_UNDERSCORE
  508.   if (symbol_name[0] == '_' && symbol_name[1] != 0)
  509.     symbol_name++;
  510. #endif /* STRIP_UNDERSCORE */
  511.  
  512.   name_end = get_symbol_end ();
  513.   symbol_name_length = strlen (symbol_name);
  514.   symbol_name_copy = xmalloc (symbol_name_length + 1);
  515.   strcpy (symbol_name_copy, symbol_name);
  516.  
  517.   /* Initialize the new symbol */
  518.   def_symbol_in_progress = symbol_make (symbol_name_copy);
  519.   def_symbol_in_progress->sy_frag = &zero_address_frag;
  520.   S_SET_VALUE (def_symbol_in_progress, 0);
  521.  
  522.   if (S_IS_STRING (def_symbol_in_progress))
  523.     SF_SET_STRING (def_symbol_in_progress);
  524.  
  525.   *input_line_pointer = name_end;
  526.  
  527.   demand_empty_rest_of_line ();
  528. }
  529.  
  530. unsigned int dim_index;
  531.  
  532. static void
  533. obj_coff_endef (ignore)
  534.      int ignore;
  535. {
  536.   symbolS *symbolP;
  537.   /* DIM BUG FIX sac@cygnus.com */
  538.   dim_index = 0;
  539.   if (def_symbol_in_progress == NULL)
  540.     {
  541.       as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
  542.       demand_empty_rest_of_line ();
  543.       return;
  544.     }                /* if not inside .def/.endef */
  545.  
  546.   /* Set the section number according to storage class. */
  547.   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
  548.     {
  549.     case C_STRTAG:
  550.     case C_ENTAG:
  551.     case C_UNTAG:
  552.       SF_SET_TAG (def_symbol_in_progress);
  553.       /* intentional fallthrough */
  554.     case C_FILE:
  555.     case C_TPDEF:
  556.       SF_SET_DEBUG (def_symbol_in_progress);
  557.       S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
  558.       break;
  559.  
  560.     case C_EFCN:
  561.       SF_SET_LOCAL (def_symbol_in_progress);    /* Do not emit this symbol. */
  562.       /* intentional fallthrough */
  563.     case C_BLOCK:
  564.       SF_SET_PROCESS (def_symbol_in_progress);    /* Will need processing before writing */
  565.       /* intentional fallthrough */
  566.     case C_FCN:
  567.       {
  568.     CONST char *name;
  569.     S_SET_SEGMENT (def_symbol_in_progress, text_section);
  570.  
  571.     name = bfd_asymbol_name (def_symbol_in_progress->bsym);
  572.     if (name[1] == 'b' && name[2] == 'f')
  573.       {
  574.         if (! in_function ())
  575.           as_warn ("`%s' symbol without preceding function", name);
  576. /*        SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/
  577.         /* Will need relocating */
  578.         SF_SET_PROCESS (def_symbol_in_progress);
  579.         clear_function ();
  580.       }
  581.       }
  582.       break;
  583.  
  584. #ifdef C_AUTOARG
  585.     case C_AUTOARG:
  586. #endif /* C_AUTOARG */
  587.     case C_AUTO:
  588.     case C_REG:
  589.     case C_MOS:
  590.     case C_MOE:
  591.     case C_MOU:
  592.     case C_ARG:
  593.     case C_REGPARM:
  594.     case C_FIELD:
  595.     case C_EOS:
  596.       SF_SET_DEBUG (def_symbol_in_progress);
  597.       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
  598.       break;
  599.  
  600.     case C_EXT:
  601.     case C_STAT:
  602.     case C_LABEL:
  603.       /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
  604.       break;
  605.  
  606.     case C_USTATIC:
  607.     case C_EXTDEF:
  608.     case C_ULABEL:
  609.       as_warn ("unexpected storage class %d",
  610.            S_GET_STORAGE_CLASS (def_symbol_in_progress));
  611.       break;
  612.     }                /* switch on storage class */
  613.  
  614.   /* Now that we have built a debug symbol, try to find if we should
  615.      merge with an existing symbol or not.  If a symbol is C_EFCN or
  616.      SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */
  617.  
  618.   /* Two cases for functions.  Either debug followed by definition or
  619.      definition followed by debug.  For definition first, we will
  620.      merge the debug symbol into the definition.  For debug first, the
  621.      lineno entry MUST point to the definition function or else it
  622.      will point off into space when obj_crawl_symbol_chain() merges
  623.      the debug symbol into the real symbol.  Therefor, let's presume
  624.      the debug symbol is a real function reference. */
  625.  
  626.   /* FIXME-SOON If for some reason the definition label/symbol is
  627.      never seen, this will probably leave an undefined symbol at link
  628.      time. */
  629.  
  630.   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
  631.       || (!strcmp (bfd_get_section_name (stdoutput,
  632.                      S_GET_SEGMENT (def_symbol_in_progress)),
  633.            "*DEBUG*")
  634.       && !SF_GET_TAG (def_symbol_in_progress))
  635.       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
  636.       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL)
  637.     {
  638.       if (def_symbol_in_progress != symbol_lastP)
  639.     symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
  640.                &symbol_lastP);
  641.     }
  642.   else
  643.     {
  644.       /* This symbol already exists, merge the newly created symbol
  645.      into the old one.  This is not mandatory. The linker can
  646.      handle duplicate symbols correctly. But I guess that it save
  647.      a *lot* of space if the assembly file defines a lot of
  648.      symbols. [loic] */
  649.  
  650.       /* The debug entry (def_symbol_in_progress) is merged into the
  651.      previous definition. */
  652.  
  653.       c_symbol_merge (def_symbol_in_progress, symbolP);
  654.       /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
  655.       def_symbol_in_progress = symbolP;
  656.  
  657.       if (SF_GET_FUNCTION (def_symbol_in_progress)
  658.       || SF_GET_TAG (def_symbol_in_progress))
  659.     {
  660.       /* For functions, and tags, the symbol *must* be where the
  661.          debug symbol appears.  Move the existing symbol to the
  662.          current place. */
  663.       /* If it already is at the end of the symbol list, do nothing */
  664.       if (def_symbol_in_progress != symbol_lastP)
  665.         {
  666.           symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
  667.           symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
  668.         }
  669.     }
  670.     }
  671.  
  672.   if (SF_GET_TAG (def_symbol_in_progress)
  673.       && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL)
  674.     {
  675.       tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress);
  676.     }
  677.  
  678.   if (SF_GET_FUNCTION (def_symbol_in_progress))
  679.     {
  680.       know (sizeof (def_symbol_in_progress) <= sizeof (long));
  681.       set_function (def_symbol_in_progress);
  682.       SF_SET_PROCESS (def_symbol_in_progress);
  683.  
  684.       if (symbolP == NULL)
  685.     {
  686.       /* That is, if this is the first time we've seen the
  687.          function... */
  688.       symbol_table_insert (def_symbol_in_progress);
  689.     } /* definition follows debug */
  690.     } /* Create the line number entry pointing to the function being defined */
  691.  
  692.   def_symbol_in_progress = NULL;
  693.   demand_empty_rest_of_line ();
  694. }
  695.  
  696. static void
  697. obj_coff_dim (ignore)
  698.      int ignore;
  699. {
  700.   int dim_index;
  701.  
  702.   if (def_symbol_in_progress == NULL)
  703.     {
  704.       as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
  705.       demand_empty_rest_of_line ();
  706.       return;
  707.     }                /* if not inside .def/.endef */
  708.  
  709.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  710.  
  711.   for (dim_index = 0; dim_index < DIMNUM; dim_index++)
  712.     {
  713.       SKIP_WHITESPACES ();
  714.       SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
  715.             get_absolute_expression ());
  716.  
  717.       switch (*input_line_pointer)
  718.     {
  719.     case ',':
  720.       input_line_pointer++;
  721.       break;
  722.  
  723.     default:
  724.       as_warn ("badly formed .dim directive ignored");
  725.       /* intentional fallthrough */
  726.     case '\n':
  727.     case ';':
  728.       dim_index = DIMNUM;
  729.       break;
  730.     }
  731.     }
  732.  
  733.   demand_empty_rest_of_line ();
  734. }
  735.  
  736. static void
  737. obj_coff_line (ignore)
  738.      int ignore;
  739. {
  740.   int this_base;
  741.  
  742.   if (def_symbol_in_progress == NULL)
  743.     {
  744.       /* Probably stabs-style line?  */
  745.       obj_coff_ln (0);
  746.       return;
  747.     }
  748.  
  749.   this_base = get_absolute_expression ();
  750.   if (!strcmp (".bf", S_GET_NAME (def_symbol_in_progress)))
  751.     coff_line_base = this_base;
  752.  
  753.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  754.   SA_SET_SYM_LNNO (def_symbol_in_progress, coff_line_base);
  755.  
  756.   demand_empty_rest_of_line ();
  757. }
  758.  
  759. static void
  760. obj_coff_size (ignore)
  761.      int ignore;
  762. {
  763.   if (def_symbol_in_progress == NULL)
  764.     {
  765.       as_warn (".size pseudo-op used outside of .def/.endef ignored.");
  766.       demand_empty_rest_of_line ();
  767.       return;
  768.     }                /* if not inside .def/.endef */
  769.  
  770.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  771.   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
  772.   demand_empty_rest_of_line ();
  773. }
  774.  
  775. static void
  776. obj_coff_scl (ignore)
  777.      int ignore;
  778. {
  779.   if (def_symbol_in_progress == NULL)
  780.     {
  781.       as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
  782.       demand_empty_rest_of_line ();
  783.       return;
  784.     }                /* if not inside .def/.endef */
  785.  
  786.   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
  787.   demand_empty_rest_of_line ();
  788. }
  789.  
  790. static void
  791. obj_coff_tag (ignore)
  792.      int ignore;
  793. {
  794.   char *symbol_name;
  795.   char name_end;
  796.  
  797.   if (def_symbol_in_progress == NULL)
  798.     {
  799.       as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
  800.       demand_empty_rest_of_line ();
  801.       return;
  802.     }
  803.  
  804.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  805.   symbol_name = input_line_pointer;
  806.   name_end = get_symbol_end ();
  807.  
  808.   /* Assume that the symbol referred to by .tag is always defined.
  809.      This was a bad assumption.  I've added find_or_make. xoxorich. */
  810.   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
  811.              tag_find_or_make (symbol_name));
  812.   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
  813.     {
  814.       as_warn ("tag not found for .tag %s", symbol_name);
  815.     }                /* not defined */
  816.  
  817.   SF_SET_TAGGED (def_symbol_in_progress);
  818.   *input_line_pointer = name_end;
  819.  
  820.   demand_empty_rest_of_line ();
  821. }
  822.  
  823. static void
  824. obj_coff_type (ignore)
  825.      int ignore;
  826. {
  827.   if (def_symbol_in_progress == NULL)
  828.     {
  829.       as_warn (".type pseudo-op used outside of .def/.endef ignored.");
  830.       demand_empty_rest_of_line ();
  831.       return;
  832.     }                /* if not inside .def/.endef */
  833.  
  834.   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
  835.  
  836.   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
  837.       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
  838.     {
  839.       SF_SET_FUNCTION (def_symbol_in_progress);
  840.     }                /* is a function */
  841.  
  842.   demand_empty_rest_of_line ();
  843. }
  844.  
  845. static void
  846. obj_coff_val (ignore)
  847.      int ignore;
  848. {
  849.   if (def_symbol_in_progress == NULL)
  850.     {
  851.       as_warn (".val pseudo-op used outside of .def/.endef ignored.");
  852.       demand_empty_rest_of_line ();
  853.       return;
  854.     }                /* if not inside .def/.endef */
  855.  
  856.   if (is_name_beginner (*input_line_pointer))
  857.     {
  858.       char *symbol_name = input_line_pointer;
  859.       char name_end = get_symbol_end ();
  860.  
  861.       if (!strcmp (symbol_name, "."))
  862.     {
  863.       def_symbol_in_progress->sy_frag = frag_now;
  864.       S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
  865.       /* If the .val is != from the .def (e.g. statics) */
  866.     }
  867.       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
  868.     {
  869.       def_symbol_in_progress->sy_value.X_op = O_symbol;
  870.       def_symbol_in_progress->sy_value.X_add_symbol =
  871.         symbol_find_or_make (symbol_name);
  872.       def_symbol_in_progress->sy_value.X_op_symbol = NULL;
  873.       def_symbol_in_progress->sy_value.X_add_number = 0;
  874.  
  875.       /* If the segment is undefined when the forward reference is
  876.          resolved, then copy the segment id from the forward
  877.          symbol.  */
  878.       SF_SET_GET_SEGMENT (def_symbol_in_progress);
  879.     }
  880.       /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
  881.       *input_line_pointer = name_end;
  882.     }
  883.   else
  884.     {
  885.       S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
  886.     }                /* if symbol based */
  887.  
  888.   demand_empty_rest_of_line ();
  889. }
  890.  
  891. void
  892. obj_read_begin_hook ()
  893. {
  894.   /* These had better be the same.  Usually 18 bytes. */
  895. #ifndef BFD_HEADERS
  896.   know (sizeof (SYMENT) == sizeof (AUXENT));
  897.   know (SYMESZ == AUXESZ);
  898. #endif
  899.   tag_init ();
  900. }
  901.  
  902.  
  903. symbolS *coff_last_function;
  904.  
  905. void
  906. coff_frob_symbol (symp, punt)
  907.      symbolS *symp;
  908.      int *punt;
  909. {
  910.   static symbolS *last_tagP;
  911.   static stack *block_stack;
  912.   static symbolS *set_end;
  913.  
  914.   if (symp == &abs_symbol)
  915.     {
  916.       *punt = 1;
  917.       return;
  918.     }
  919.  
  920.   if (current_lineno_sym)
  921.     coff_add_linesym ((symbolS *) 0);
  922.  
  923.   if (!block_stack)
  924.     block_stack = stack_init (512, sizeof (symbolS*));
  925.  
  926.   if (!S_IS_DEFINED (symp) && S_GET_STORAGE_CLASS (symp) != C_STAT)
  927.     S_SET_STORAGE_CLASS (symp, C_EXT);
  928.  
  929.   if (!SF_GET_DEBUG (symp))
  930.     {
  931.       symbolS *real;
  932.       if (!SF_GET_LOCAL (symp)
  933.       && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
  934.       && real != symp)
  935.     {
  936.       c_symbol_merge (symp, real);
  937.       *punt = 1;
  938.     }
  939.       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
  940.     {
  941.       assert (S_GET_VALUE (symp) == 0);
  942.       S_SET_EXTERNAL (symp);
  943.     }
  944.       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
  945.     {
  946.       if (S_GET_SEGMENT (symp) == text_section
  947.           && symp != seg_info (text_section)->sym)
  948.         S_SET_STORAGE_CLASS (symp, C_LABEL);
  949.       else
  950.         S_SET_STORAGE_CLASS (symp, C_STAT);
  951.     }
  952.       if (SF_GET_PROCESS (symp))
  953.     {
  954.       if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
  955.         {
  956.           if (!strcmp (S_GET_NAME (symp), ".bb"))
  957.         stack_push (block_stack, (char *) &symp);
  958.           else
  959.         {
  960.           symbolS *begin;
  961.           begin = *(symbolS **) stack_pop (block_stack);
  962.           if (begin == 0)
  963.             as_warn ("mismatched .eb");
  964.           else
  965.             set_end = begin;
  966.         }
  967.         }
  968.       if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
  969.         {
  970.           union internal_auxent *auxp;
  971.           coff_last_function = symp;
  972.           if (S_GET_NUMBER_AUXILIARY (symp) < 1)
  973.         S_SET_NUMBER_AUXILIARY (symp, 1);
  974.           auxp = &coffsymbol (symp->bsym)->native[1].u.auxent;
  975.           memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
  976.               sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
  977.         }
  978.       if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
  979.         {
  980.           if (coff_last_function == 0)
  981.         as_fatal ("C_EFCN symbol out of scope");
  982.           SA_SET_SYM_FSIZE (coff_last_function,
  983.                 (long) (S_GET_VALUE (symp)
  984.                     - S_GET_VALUE (coff_last_function)));
  985.           set_end = coff_last_function;
  986.           coff_last_function = 0;
  987.         }
  988.     }
  989.       else if (SF_GET_TAG (symp))
  990.     last_tagP = symp;
  991.       else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
  992.     set_end = last_tagP;
  993.       else if (S_GET_STORAGE_CLASS (symp) == C_FILE)
  994.     {
  995.       if (S_GET_VALUE (symp))
  996.         {
  997.           S_SET_VALUE ((symbolS *) S_GET_VALUE (symp), 0xdeadbeef);
  998.           S_SET_VALUE (symp, 0);
  999.         }
  1000.     }
  1001.       if (S_IS_EXTERNAL (symp))
  1002.     S_SET_STORAGE_CLASS (symp, C_EXT);
  1003.       else if (SF_GET_LOCAL (symp))
  1004.     *punt = 1;
  1005.       /* more ... */
  1006.     }
  1007.  
  1008.   if (set_end != (symbolS *) NULL
  1009.       && ! *punt)
  1010.     {
  1011.       SA_SET_SYM_ENDNDX (set_end, symp);
  1012.       set_end = NULL;
  1013.     }
  1014.  
  1015.   if (coffsymbol (symp->bsym)->lineno)
  1016.     {
  1017.       int i;
  1018.       struct line_no *lptr;
  1019.       alent *l;
  1020.  
  1021.       lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
  1022.       for (i = 0; lptr; lptr = lptr->next)
  1023.     i++;
  1024.       lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
  1025.  
  1026.       /* We need i entries for line numbers, plus 1 for the first
  1027.      entry which BFD will override, plus 1 for the last zero
  1028.      entry (a marker for BFD).  */
  1029.       l = (alent *) bfd_alloc_by_size_t (stdoutput, (i + 2) * sizeof (alent));
  1030.       coffsymbol (symp->bsym)->lineno = l;
  1031.       l[i + 1].line_number = 0;
  1032.       l[i + 1].u.sym = NULL;
  1033.       for (; i > 0; i--)
  1034.     {
  1035.       if (lptr->frag)
  1036.         lptr->l.u.offset += lptr->frag->fr_address;
  1037.       l[i] = lptr->l;
  1038.       lptr = lptr->next;
  1039.     }
  1040.     }
  1041. }
  1042.  
  1043. void
  1044. coff_adjust_section_syms (abfd, sec, x)
  1045.      bfd *abfd;
  1046.      asection *sec;
  1047.      PTR x;
  1048. {
  1049.   symbolS *secsym;
  1050.   segment_info_type *seginfo = seg_info (sec);
  1051.   int nlnno, nrelocs = 0;
  1052.  
  1053.   /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
  1054.      tc-ppc.c.  Do not get confused by it.  */
  1055.   if (seginfo == NULL)
  1056.     return;
  1057.  
  1058.   if (!strcmp (sec->name, ".text"))
  1059.     nlnno = n_line_nos;
  1060.   else
  1061.     nlnno = 0;
  1062.   {
  1063.     /* @@ Hope that none of the fixups expand to more than one reloc
  1064.        entry...  */
  1065.     fixS *fixp = seginfo->fix_root;
  1066.     while (fixp)
  1067.       {
  1068.     fixp = fixp->fx_next;
  1069.     nrelocs++;
  1070.       }
  1071.   }
  1072.   if (bfd_get_section_size_before_reloc (sec) == 0
  1073.       && nrelocs == 0 && nlnno == 0)
  1074.     return;
  1075.   secsym = section_symbol (sec);
  1076.   SA_SET_SCN_NRELOC (secsym, nrelocs);
  1077.   SA_SET_SCN_NLINNO (secsym, nlnno);
  1078. }
  1079.  
  1080. void
  1081. coff_frob_file ()
  1082. {
  1083.   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
  1084. }
  1085.  
  1086. /*
  1087.  * implement the .section pseudo op:
  1088.  *    .section name {, "flags"}
  1089.  *                ^         ^
  1090.  *                |         +--- optional flags: 'b' for bss
  1091.  *                |                              'i' for info
  1092.  *                +-- section name               'l' for lib
  1093.  *                                               'n' for noload
  1094.  *                                               'o' for over
  1095.  *                                               'w' for data
  1096.  *                         'd' (apparently m88k for data)
  1097.  *                                               'x' for text
  1098.  * But if the argument is not a quoted string, treat it as a
  1099.  * subsegment number.
  1100.  */
  1101.  
  1102. void
  1103. obj_coff_section (ignore)
  1104.      int ignore;
  1105. {
  1106.   /* Strip out the section name */
  1107.   char *section_name;
  1108.   char c;
  1109.   char *name;
  1110.   unsigned int exp;
  1111.   flagword flags;
  1112.   asection *sec;
  1113.  
  1114.   section_name = input_line_pointer;
  1115.   c = get_symbol_end ();
  1116.  
  1117.   name = xmalloc (input_line_pointer - section_name + 1);
  1118.   strcpy (name, section_name);
  1119.  
  1120.   *input_line_pointer = c;
  1121.  
  1122.   SKIP_WHITESPACE ();
  1123.  
  1124.   exp = 0;
  1125.   flags = SEC_NO_FLAGS;
  1126.  
  1127.   if (*input_line_pointer == ',')
  1128.     {
  1129.       ++input_line_pointer;
  1130.       SKIP_WHITESPACE ();
  1131.       if (*input_line_pointer != '"')
  1132.     exp = get_absolute_expression ();
  1133.       else
  1134.     {
  1135.       ++input_line_pointer;
  1136.       while (*input_line_pointer != '"'
  1137.          && ! is_end_of_line[(unsigned char) *input_line_pointer])
  1138.         {
  1139.           switch (*input_line_pointer)
  1140.         {
  1141.         case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
  1142.         case 'n': flags &=~ SEC_LOAD; break;
  1143.         case 'd':
  1144.         case 'w': flags &=~ SEC_READONLY; break;
  1145.         case 'x': flags |= SEC_CODE; break;
  1146.  
  1147.         case 'i': /* STYP_INFO */
  1148.         case 'l': /* STYP_LIB */
  1149.         case 'o': /* STYP_OVER */
  1150.           as_warn ("unsupported section attribute '%c'",
  1151.                *input_line_pointer);
  1152.           break;
  1153.  
  1154.         default:
  1155.           as_warn("unknown section attribute '%c'",
  1156.               *input_line_pointer);
  1157.           break;
  1158.         }
  1159.           ++input_line_pointer;
  1160.         }
  1161.       if (*input_line_pointer == '"')
  1162.         ++input_line_pointer;
  1163.     }
  1164.     }
  1165.  
  1166.   sec = subseg_new (name, (subsegT) exp);
  1167.  
  1168.   if (flags != SEC_NO_FLAGS)
  1169.     {
  1170.       if (! bfd_set_section_flags (stdoutput, sec, flags))
  1171.     as_warn ("error setting flags for \"%s\": %s",
  1172.          bfd_section_name (stdoutput, sec),
  1173.          bfd_errmsg (bfd_get_error ()));
  1174.     }
  1175. }
  1176.  
  1177. void
  1178. coff_adjust_symtab ()
  1179. {
  1180.   if (symbol_rootP == NULL
  1181.       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
  1182.     {
  1183.       assert (previous_file_symbol == 0);
  1184.       c_dot_file_symbol ("fake");
  1185.     }
  1186. }
  1187.  
  1188. void
  1189. coff_frob_section (sec)
  1190.      segT sec;
  1191. {
  1192.   segT strsec;
  1193.   char *strname, *p;
  1194.   fragS *fragp;
  1195.   bfd_vma size, n_entries, mask;
  1196.  
  1197.   /* The COFF back end in BFD requires that all section sizes be
  1198.      rounded up to multiples of the corresponding section alignments.
  1199.      Seems kinda silly to me, but that's the way it is.  */
  1200.   size = bfd_get_section_size_before_reloc (sec);
  1201.   mask = ((bfd_vma) 1 << (bfd_vma) sec->alignment_power) - 1;
  1202.   if (size & mask)
  1203.     {
  1204.       size = (size + mask) & ~mask;
  1205.       bfd_set_section_size (stdoutput, sec, size);
  1206.     }
  1207.  
  1208.   /* If the section size is non-zero, the section symbol needs an aux
  1209.      entry associated with it, indicating the size.  We don't know
  1210.      all the values yet; coff_frob_symbol will fill them in later.  */
  1211.   if (size)
  1212.     {
  1213.       symbolS *secsym = section_symbol (sec);
  1214.  
  1215.       S_SET_STORAGE_CLASS (secsym, C_STAT);
  1216.       S_SET_NUMBER_AUXILIARY (secsym, 1);
  1217.       SF_SET_STATICS (secsym);
  1218.       SA_SET_SCN_SCNLEN (secsym, size);
  1219.     }
  1220.  
  1221.   /* @@ these should be in a "stabs.h" file, or maybe as.h */
  1222. #ifndef STAB_SECTION_NAME
  1223. #define STAB_SECTION_NAME ".stab"
  1224. #endif
  1225. #ifndef STAB_STRING_SECTION_NAME
  1226. #define STAB_STRING_SECTION_NAME ".stabstr"
  1227. #endif
  1228.   if (strcmp (STAB_STRING_SECTION_NAME, sec->name))
  1229.     return;
  1230.  
  1231.   strsec = sec;
  1232.   sec = subseg_get (STAB_SECTION_NAME, 0);
  1233.   /* size is already rounded up, since other section will be listed first */
  1234.   size = bfd_get_section_size_before_reloc (strsec);
  1235.  
  1236.   n_entries = bfd_get_section_size_before_reloc (sec) / 12 - 1;
  1237.  
  1238.   /* Find first non-empty frag.  It should be large enough.  */
  1239.   fragp = seg_info (sec)->frchainP->frch_root;
  1240.   while (fragp && fragp->fr_fix == 0)
  1241.     fragp = fragp->fr_next;
  1242.   assert (fragp != 0 && fragp->fr_fix >= 12);
  1243.  
  1244.   /* Store the values.  */
  1245.   p = fragp->fr_literal;
  1246.   bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
  1247.   bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
  1248. }
  1249.  
  1250. void
  1251. obj_coff_init_stab_section (seg)
  1252.      segT seg;
  1253. {
  1254.   char *file;
  1255.   char *p;
  1256.   char *stabstr_name;
  1257.   unsigned int stroff;
  1258.  
  1259.   /* Make space for this first symbol. */
  1260.   p = frag_more (12);
  1261.   /* Zero it out. */
  1262.   memset (p, 0, 12);
  1263.   as_where (&file, (unsigned int *) NULL);
  1264.   stabstr_name = (char *) alloca (strlen (seg->name) + 4);
  1265.   strcpy (stabstr_name, seg->name);
  1266.   strcat (stabstr_name, "str");
  1267.   stroff = get_stab_string_offset (file, stabstr_name);
  1268.   know (stroff == 1);
  1269.   md_number_to_chars (p, stroff, 4);
  1270. }
  1271.  
  1272. #ifdef DEBUG
  1273. /* for debugging */
  1274. const char *
  1275. s_get_name (s)
  1276.      symbolS *s;
  1277. {
  1278.   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
  1279. }
  1280.  
  1281. void
  1282. symbol_dump ()
  1283. {
  1284.   symbolS *symbolP;
  1285.  
  1286.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  1287.     {
  1288.       printf("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n",
  1289.          (unsigned long) symbolP,
  1290.          S_GET_NAME(symbolP),
  1291.          (long) S_GET_DATA_TYPE(symbolP),
  1292.          S_GET_STORAGE_CLASS(symbolP),
  1293.          (int) S_GET_SEGMENT(symbolP));
  1294.     }
  1295. }
  1296.  
  1297. #endif /* DEBUG */
  1298.  
  1299. #else /* not BFD_ASSEMBLER */
  1300.  
  1301. #include "frags.h"
  1302. /* This is needed because we include internal bfd things. */
  1303. #include <time.h>
  1304. #include "../bfd/libbfd.h"
  1305. #include "../bfd/libcoff.h"
  1306.  
  1307. /* The NOP_OPCODE is for the alignment fill value.  Fill with nop so
  1308.    that we can stick sections together without causing trouble.  */
  1309. #ifndef NOP_OPCODE
  1310. #define NOP_OPCODE 0x00
  1311. #endif
  1312.  
  1313. /* The zeroes if symbol name is longer than 8 chars */
  1314. #define S_SET_ZEROES(s,v)        ((s)->sy_symbol.ost_entry.n_zeroes = (v))
  1315.  
  1316. #define MIN(a,b) ((a) < (b)? (a) : (b))
  1317. /* This vector is used to turn an internal segment into a section #
  1318.    suitable for insertion into a coff symbol table
  1319.  */
  1320.  
  1321. const short seg_N_TYPE[] =
  1322. {                /* in: segT   out: N_TYPE bits */
  1323.   C_ABS_SECTION,
  1324.   1,
  1325.   2,
  1326.   3,
  1327.   4,
  1328.   5,
  1329.   6,
  1330.   7,
  1331.   8,
  1332.   9,
  1333.   10,
  1334.   C_UNDEF_SECTION,        /* SEG_UNKNOWN */
  1335.   C_UNDEF_SECTION,        /* SEG_GOOF */
  1336.   C_UNDEF_SECTION,        /* SEG_EXPR */
  1337.   C_DEBUG_SECTION,        /* SEG_DEBUG */
  1338.   C_NTV_SECTION,        /* SEG_NTV */
  1339.   C_PTV_SECTION,        /* SEG_PTV */
  1340.   C_REGISTER_SECTION,        /* SEG_REGISTER */
  1341. };
  1342.  
  1343. int function_lineoff = -1;    /* Offset in line#s where the last function
  1344.                    started (the odd entry for line #0) */
  1345.  
  1346. static symbolS *last_line_symbol;
  1347.  
  1348. /* Add 4 to the real value to get the index and compensate the
  1349.    negatives. This vector is used by S_GET_SEGMENT to turn a coff
  1350.    section number into a segment number
  1351. */
  1352. static symbolS *previous_file_symbol;
  1353. void c_symbol_merge ();
  1354. static int line_base;
  1355.  
  1356. symbolS *c_section_symbol ();
  1357. bfd *abfd;
  1358.  
  1359. static void fixup_segment PARAMS ((segment_info_type *segP,
  1360.                    segT this_segment_type));
  1361.  
  1362.  
  1363. static void fixup_mdeps PARAMS ((fragS *,
  1364.                  object_headers *,
  1365.                  segT));
  1366.  
  1367.  
  1368. static void fill_section PARAMS ((bfd * abfd,
  1369.                   object_headers *,
  1370.                   unsigned long *));
  1371.  
  1372.  
  1373. static int c_line_new PARAMS ((symbolS * symbol, long paddr,
  1374.                    int line_number,
  1375.                    fragS * frag));
  1376.  
  1377.  
  1378. static void w_symbols PARAMS ((bfd * abfd, char *where,
  1379.                    symbolS * symbol_rootP));
  1380.  
  1381. static void adjust_stab_section PARAMS ((bfd *abfd, segT seg));
  1382.  
  1383. static void obj_coff_lcomm PARAMS ((int));
  1384. static void obj_coff_text PARAMS ((int));
  1385. static void obj_coff_data PARAMS ((int));
  1386. static void obj_coff_bss PARAMS ((int));
  1387. static void obj_coff_ident PARAMS ((int));
  1388. void obj_coff_section PARAMS ((int));
  1389.  
  1390. /* Section stuff
  1391.  
  1392.    We allow more than just the standard 3 sections, infact, we allow
  1393.    10 sections, (though the usual three have to be there).
  1394.  
  1395.    This structure performs the mappings for us:
  1396.  
  1397. */
  1398.  
  1399. #define N_SEG 32
  1400. typedef struct
  1401. {
  1402.   segT seg_t;
  1403.   int i;
  1404. } seg_info_type;
  1405.  
  1406. static const seg_info_type seg_info_off_by_4[N_SEG] =
  1407. {
  1408.  {SEG_PTV,  },
  1409.  {SEG_NTV,  },
  1410.  {SEG_DEBUG, },
  1411.  {SEG_ABSOLUTE,  },
  1412.  {SEG_UNKNOWN,     },
  1413.  {SEG_E0},
  1414.  {SEG_E1},
  1415.  {SEG_E2},
  1416.  {SEG_E3},
  1417.  {SEG_E4},
  1418.  {SEG_E5},
  1419.  {SEG_E6},
  1420.  {SEG_E7},
  1421.  {SEG_E8},
  1422.  {SEG_E9},
  1423.  {(segT)15},
  1424.  {(segT)16},
  1425.  {(segT)17},
  1426.  {(segT)18},
  1427.  {(segT)19},
  1428.  {(segT)20},
  1429.  {(segT)0},
  1430.  {(segT)0},
  1431.  {(segT)0},
  1432.  {SEG_REGISTER}
  1433. };
  1434.  
  1435.  
  1436.  
  1437. #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
  1438.  
  1439. static relax_addressT
  1440. relax_align (address, alignment)
  1441.      relax_addressT address;
  1442.      long alignment;
  1443. {
  1444.   relax_addressT mask;
  1445.   relax_addressT new_address;
  1446.  
  1447.   mask = ~((~0) << alignment);
  1448.   new_address = (address + mask) & (~mask);
  1449.   return (new_address - address);
  1450. }
  1451.  
  1452.  
  1453. segT
  1454. s_get_segment (x)
  1455.      symbolS * x;
  1456. {
  1457.   return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum).seg_t;
  1458. }
  1459.  
  1460.  
  1461.  
  1462. /* calculate the size of the frag chain and fill in the section header
  1463.    to contain all of it, also fill in the addr of the sections */
  1464. static unsigned int
  1465. size_section (abfd, idx)
  1466.      bfd * abfd;
  1467.      unsigned int idx;
  1468. {
  1469.  
  1470.   unsigned int size = 0;
  1471.   fragS *frag = segment_info[idx].frchainP->frch_root;
  1472.   while (frag)
  1473.     {
  1474.       size = frag->fr_address;
  1475.       if (frag->fr_address != size)
  1476.     {
  1477.       fprintf (stderr, "Out of step\n");
  1478.       size = frag->fr_address;
  1479.     }
  1480.  
  1481.       switch (frag->fr_type)
  1482.     {
  1483. #ifdef TC_COFF_SIZEMACHDEP
  1484.     case rs_machine_dependent:
  1485.       size += TC_COFF_SIZEMACHDEP (frag);
  1486.       break;
  1487. #endif
  1488.     case rs_fill:
  1489.     case rs_org:
  1490.       size += frag->fr_fix;
  1491.       size += frag->fr_offset * frag->fr_var;
  1492.       break;
  1493.     case rs_align:
  1494.       size += frag->fr_fix;
  1495.       size += relax_align (size, frag->fr_offset);
  1496.       break;
  1497.     default:
  1498.       BAD_CASE (frag->fr_type);
  1499.       break;
  1500.     }
  1501.       frag = frag->fr_next;
  1502.     }
  1503.   segment_info[idx].scnhdr.s_size = size;
  1504.   return size;
  1505. }
  1506.  
  1507.  
  1508. static unsigned int
  1509. count_entries_in_chain (idx)
  1510.      unsigned int idx;
  1511. {
  1512.   unsigned int nrelocs;
  1513.   fixS *fixup_ptr;
  1514.  
  1515.   /* Count the relocations */
  1516.   fixup_ptr = segment_info[idx].fix_root;
  1517.   nrelocs = 0;
  1518.   while (fixup_ptr != (fixS *) NULL)
  1519.     {
  1520.       if (TC_COUNT_RELOC (fixup_ptr))
  1521.     {
  1522. #ifdef TC_A29K
  1523.       if (fixup_ptr->fx_r_type == RELOC_CONSTH)
  1524.         nrelocs += 2;
  1525.       else
  1526.         nrelocs++;
  1527. #else
  1528.       nrelocs++;
  1529. #endif
  1530.     }
  1531.  
  1532.       fixup_ptr = fixup_ptr->fx_next;
  1533.     }
  1534.   return nrelocs;
  1535. }
  1536.  
  1537. /* output all the relocations for a section */
  1538. void
  1539. do_relocs_for (abfd, h, file_cursor)
  1540.      bfd * abfd;
  1541.      object_headers * h;
  1542.      unsigned long *file_cursor;
  1543. {
  1544.   unsigned int nrelocs;
  1545.   unsigned int idx;
  1546.   unsigned long reloc_start = *file_cursor;
  1547.  
  1548.   for (idx = SEG_E0; idx < SEG_E9; idx++)
  1549.     {
  1550.       if (segment_info[idx].scnhdr.s_name[0])
  1551.     {
  1552.       struct external_reloc *ext_ptr;
  1553.       struct external_reloc *external_reloc_vec;
  1554.       unsigned int external_reloc_size;
  1555.       unsigned int base = segment_info[idx].scnhdr.s_paddr;
  1556.       fixS *fix_ptr = segment_info[idx].fix_root;
  1557.       nrelocs = count_entries_in_chain (idx);
  1558.  
  1559.       if (nrelocs)
  1560.         /* Bypass this stuff if no relocs.  This also incidentally
  1561.            avoids a SCO bug, where free(malloc(0)) tends to crash.  */
  1562.         {
  1563.           external_reloc_size = nrelocs * RELSZ;
  1564.           external_reloc_vec =
  1565.         (struct external_reloc *) malloc (external_reloc_size);
  1566.  
  1567.           ext_ptr = external_reloc_vec;
  1568.  
  1569.           /* Fill in the internal coff style reloc struct from the
  1570.          internal fix list.  */
  1571.           while (fix_ptr)
  1572.         {
  1573.           symbolS *symbol_ptr;
  1574.           struct internal_reloc intr;
  1575.  
  1576.           /* Only output some of the relocations */
  1577.           if (TC_COUNT_RELOC (fix_ptr))
  1578.             {
  1579. #ifdef TC_RELOC_MANGLE
  1580.               TC_RELOC_MANGLE (fix_ptr, &intr, base);
  1581.  
  1582. #else
  1583.               symbolS *dot;
  1584.               symbol_ptr = fix_ptr->fx_addsy;
  1585.  
  1586.               intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
  1587.               intr.r_vaddr =
  1588.             base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
  1589.  
  1590. #ifdef TC_KEEP_FX_OFFSET
  1591.               intr.r_offset = fix_ptr->fx_offset;
  1592. #else
  1593.               intr.r_offset = 0;
  1594. #endif
  1595.  
  1596.               /* Turn the segment of the symbol into an offset.  */
  1597.               if (symbol_ptr)
  1598.             {
  1599.               dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
  1600.               if (dot)
  1601.                 {
  1602.                   intr.r_symndx = dot->sy_number;
  1603.                 }
  1604.               else
  1605.                 {
  1606.                   intr.r_symndx = symbol_ptr->sy_number;
  1607.                 }
  1608.  
  1609.             }
  1610.               else
  1611.             {
  1612.               intr.r_symndx = -1;
  1613.             }
  1614. #endif
  1615.  
  1616.               (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
  1617.               ext_ptr++;
  1618.  
  1619. #if defined(TC_A29K)
  1620.  
  1621.               /* The 29k has a special kludge for the high 16 bit
  1622.              reloc.  Two relocations are emited, R_IHIHALF,
  1623.              and R_IHCONST. The second one doesn't contain a
  1624.              symbol, but uses the value for offset.  */
  1625.  
  1626.               if (intr.r_type == R_IHIHALF)
  1627.             {
  1628.               /* now emit the second bit */
  1629.               intr.r_type = R_IHCONST;
  1630.               intr.r_symndx = fix_ptr->fx_addnumber;
  1631.               (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
  1632.               ext_ptr++;
  1633.             }
  1634. #endif
  1635.             }
  1636.  
  1637.           fix_ptr = fix_ptr->fx_next;
  1638.         }
  1639.  
  1640.           /* Write out the reloc table */
  1641.           bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size,
  1642.              abfd);
  1643.           free (external_reloc_vec);
  1644.  
  1645.           /* Fill in section header info.  */
  1646.           segment_info[idx].scnhdr.s_relptr = *file_cursor;
  1647.           *file_cursor += external_reloc_size;
  1648.           segment_info[idx].scnhdr.s_nreloc = nrelocs;
  1649.         }
  1650.       else
  1651.         {
  1652.           /* No relocs */
  1653.           segment_info[idx].scnhdr.s_relptr = 0;
  1654.         }
  1655.     }
  1656.     }
  1657.   /* Set relocation_size field in file headers */
  1658.   H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
  1659. }
  1660.  
  1661.  
  1662. /* run through a frag chain and write out the data to go with it, fill
  1663.    in the scnhdrs with the info on the file postions
  1664. */
  1665. static void
  1666. fill_section (abfd, h, file_cursor)
  1667.      bfd * abfd;
  1668.      object_headers *h;
  1669.      unsigned long *file_cursor;
  1670. {
  1671.  
  1672.   unsigned int i;
  1673.   unsigned int paddr = 0;
  1674.  
  1675.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  1676.     {
  1677.       unsigned int offset = 0;
  1678.  
  1679.       struct internal_scnhdr *s = &(segment_info[i].scnhdr);
  1680.  
  1681.       if (s->s_name[0])
  1682.     {
  1683.       fragS *frag = segment_info[i].frchainP->frch_root;
  1684.       char *buffer;
  1685.  
  1686.       if (s->s_size == 0)
  1687.         s->s_scnptr = 0;
  1688.       else
  1689.         {
  1690.           buffer = xmalloc (s->s_size);
  1691.           s->s_scnptr = *file_cursor;
  1692.         }
  1693.       know (s->s_paddr == paddr);
  1694.  
  1695.       if (strcmp (s->s_name, ".text") == 0)
  1696.         s->s_flags |= STYP_TEXT;
  1697.       else if (strcmp (s->s_name, ".data") == 0)
  1698.         s->s_flags |= STYP_DATA;
  1699.       else if (strcmp (s->s_name, ".bss") == 0)
  1700.         {
  1701.           s->s_scnptr = 0;
  1702.           s->s_flags |= STYP_BSS;
  1703.  
  1704.           /* @@ Should make the i386 and a29k coff targets define
  1705.          COFF_NOLOAD_PROBLEM, and have only one test here.  */
  1706. #ifndef TC_I386
  1707. #ifndef TC_A29K
  1708. #ifndef COFF_NOLOAD_PROBLEM
  1709.           /* Apparently the SVR3 linker (and exec syscall) and UDI
  1710.          mondfe progrem are confused by noload sections.  */
  1711.           s->s_flags |= STYP_NOLOAD;
  1712. #endif
  1713. #endif
  1714. #endif
  1715.         }
  1716.       else if (strcmp (s->s_name, ".lit") == 0)
  1717.         s->s_flags = STYP_LIT | STYP_TEXT;
  1718.       else if (strcmp (s->s_name, ".init") == 0)
  1719.         s->s_flags |= STYP_TEXT;
  1720.       else if (strcmp (s->s_name, ".fini") == 0)
  1721.         s->s_flags |= STYP_TEXT;
  1722.       else if (strncmp (s->s_name, ".comment", 8) == 0)
  1723.         s->s_flags |= STYP_INFO;
  1724.  
  1725.       while (frag)
  1726.         {
  1727.           unsigned int fill_size;
  1728.           switch (frag->fr_type)
  1729.         {
  1730.         case rs_machine_dependent:
  1731.           if (frag->fr_fix)
  1732.             {
  1733.               memcpy (buffer + frag->fr_address,
  1734.                   frag->fr_literal,
  1735.                   (unsigned int) frag->fr_fix);
  1736.               offset += frag->fr_fix;
  1737.             }
  1738.  
  1739.           break;
  1740.         case rs_fill:
  1741.         case rs_align:
  1742.         case rs_org:
  1743.           if (frag->fr_fix)
  1744.             {
  1745.               memcpy (buffer + frag->fr_address,
  1746.                   frag->fr_literal,
  1747.                   (unsigned int) frag->fr_fix);
  1748.               offset += frag->fr_fix;
  1749.             }
  1750.  
  1751.           fill_size = frag->fr_var;
  1752.           if (fill_size && frag->fr_offset > 0)
  1753.             {
  1754.               unsigned int count;
  1755.               unsigned int off = frag->fr_fix;
  1756.               for (count = frag->fr_offset; count; count--)
  1757.             {
  1758.               if (fill_size + frag->fr_address + off <= s->s_size)
  1759.                 {
  1760.                   memcpy (buffer + frag->fr_address + off,
  1761.                       frag->fr_literal + frag->fr_fix,
  1762.                       fill_size);
  1763.                   off += fill_size;
  1764.                   offset += fill_size;
  1765.                 }
  1766.             }
  1767.             }
  1768.           break;
  1769.         case rs_broken_word:
  1770.           break;
  1771.         default:
  1772.           abort ();
  1773.         }
  1774.           frag = frag->fr_next;
  1775.         }
  1776.  
  1777.       if (s->s_size != 0)
  1778.         {
  1779.           if (s->s_scnptr != 0)
  1780.         {
  1781.           bfd_write (buffer, s->s_size, 1, abfd);
  1782.           *file_cursor += s->s_size;
  1783.         }
  1784.           free (buffer);
  1785.         }
  1786.       paddr += s->s_size;
  1787.     }
  1788.     }
  1789. }
  1790.  
  1791. /* Coff file generation & utilities */
  1792.  
  1793. static void
  1794. coff_header_append (abfd, h)
  1795.      bfd * abfd;
  1796.      object_headers * h;
  1797. {
  1798.   unsigned int i;
  1799.   char buffer[1000];
  1800.   char buffero[1000];
  1801.  
  1802.   bfd_seek (abfd, 0, 0);
  1803.  
  1804. #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
  1805.   H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
  1806.   H_SET_VERSION_STAMP (h, 0);
  1807.   H_SET_ENTRY_POINT (h, 0);
  1808.   H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
  1809.   H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
  1810.   H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
  1811.                                  buffero));
  1812. #else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
  1813.   H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
  1814. #endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
  1815.  
  1816.   i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
  1817.  
  1818.   bfd_write (buffer, i, 1, abfd);
  1819.   bfd_write (buffero, H_GET_SIZEOF_OPTIONAL_HEADER (h), 1, abfd);
  1820.  
  1821.   for (i = SEG_E0; i < SEG_E9; i++)
  1822.     {
  1823.       if (segment_info[i].scnhdr.s_name[0])
  1824.     {
  1825.       unsigned int size =
  1826.       bfd_coff_swap_scnhdr_out (abfd,
  1827.                     &(segment_info[i].scnhdr),
  1828.                     buffer);
  1829.       bfd_write (buffer, size, 1, abfd);
  1830.     }
  1831.     }
  1832. }
  1833.  
  1834.  
  1835. char *
  1836. symbol_to_chars (abfd, where, symbolP)
  1837.      bfd * abfd;
  1838.      char *where;
  1839.      symbolS * symbolP;
  1840. {
  1841.   unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
  1842.   unsigned int i;
  1843.   valueT val;
  1844.  
  1845.   /* Turn any symbols with register attributes into abs symbols */
  1846.   if (S_GET_SEGMENT (symbolP) == reg_section)
  1847.     {
  1848.       S_SET_SEGMENT (symbolP, absolute_section);
  1849.     }
  1850.   /* At the same time, relocate all symbols to their output value */
  1851.  
  1852.   val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
  1853.      + S_GET_VALUE (symbolP));
  1854.  
  1855.   S_SET_VALUE (symbolP, val);
  1856.  
  1857.   symbolP->sy_symbol.ost_entry.n_value = val;
  1858.  
  1859.   where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
  1860.                   where);
  1861.  
  1862.   for (i = 0; i < numaux; i++)
  1863.     {
  1864.       where += bfd_coff_swap_aux_out (abfd,
  1865.                       &symbolP->sy_symbol.ost_auxent[i],
  1866.                       S_GET_DATA_TYPE (symbolP),
  1867.                       S_GET_STORAGE_CLASS (symbolP),
  1868.                       i, numaux, where);
  1869.     }
  1870.   return where;
  1871.  
  1872. }
  1873.  
  1874. void
  1875. obj_symbol_new_hook (symbolP)
  1876.      symbolS *symbolP;
  1877. {
  1878.   char underscore = 0;        /* Symbol has leading _ */
  1879.  
  1880.   /* Effective symbol */
  1881.   /* Store the pointer in the offset. */
  1882.   S_SET_ZEROES (symbolP, 0L);
  1883.   S_SET_DATA_TYPE (symbolP, T_NULL);
  1884.   S_SET_STORAGE_CLASS (symbolP, 0);
  1885.   S_SET_NUMBER_AUXILIARY (symbolP, 0);
  1886.   /* Additional information */
  1887.   symbolP->sy_symbol.ost_flags = 0;
  1888.   /* Auxiliary entries */
  1889.   memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);
  1890.  
  1891.   if (S_IS_STRING (symbolP))
  1892.     SF_SET_STRING (symbolP);
  1893.   if (!underscore && S_IS_LOCAL (symbolP))
  1894.     SF_SET_LOCAL (symbolP);
  1895. }
  1896.  
  1897. /*
  1898.  * Handle .ln directives.
  1899.  */
  1900.  
  1901. static void
  1902. obj_coff_ln (appline)
  1903.      int appline;
  1904. {
  1905.   int l;
  1906.  
  1907.   if (! appline && def_symbol_in_progress != NULL)
  1908.     {
  1909.       as_warn (".ln pseudo-op inside .def/.endef: ignored.");
  1910.       demand_empty_rest_of_line ();
  1911.       return;
  1912.     }                /* wrong context */
  1913.  
  1914.   l = get_absolute_expression ();
  1915.   c_line_new (0, obstack_next_free (&frags) - frag_now->fr_literal, l,
  1916.           frag_now);
  1917. #ifndef NO_LISTING
  1918.   {
  1919.     extern int listing;
  1920.  
  1921.     if (listing)
  1922.       {
  1923.     if (! appline)
  1924.       l += line_base - 1;
  1925.     listing_source_line ((unsigned int) l);
  1926.       }
  1927.  
  1928.   }
  1929. #endif
  1930.   demand_empty_rest_of_line ();
  1931. }
  1932.  
  1933. /*
  1934.  *            def()
  1935.  *
  1936.  * Handle .def directives.
  1937.  *
  1938.  * One might ask : why can't we symbol_new if the symbol does not
  1939.  * already exist and fill it with debug information.  Because of
  1940.  * the C_EFCN special symbol. It would clobber the value of the
  1941.  * function symbol before we have a chance to notice that it is
  1942.  * a C_EFCN. And a second reason is that the code is more clear this
  1943.  * way. (at least I think it is :-).
  1944.  *
  1945.  */
  1946.  
  1947. #define SKIP_SEMI_COLON()    while (*input_line_pointer++ != ';')
  1948. #define SKIP_WHITESPACES()    while (*input_line_pointer == ' ' || \
  1949.                       *input_line_pointer == '\t') \
  1950.                                          input_line_pointer++;
  1951.  
  1952. static void
  1953. obj_coff_def (what)
  1954.      int what;
  1955. {
  1956.   char name_end;        /* Char after the end of name */
  1957.   char *symbol_name;        /* Name of the debug symbol */
  1958.   char *symbol_name_copy;    /* Temporary copy of the name */
  1959.   unsigned int symbol_name_length;
  1960.  
  1961.   if (def_symbol_in_progress != NULL)
  1962.     {
  1963.       as_warn (".def pseudo-op used inside of .def/.endef: ignored.");
  1964.       demand_empty_rest_of_line ();
  1965.       return;
  1966.     }                /* if not inside .def/.endef */
  1967.  
  1968.   SKIP_WHITESPACES ();
  1969.  
  1970.   def_symbol_in_progress = (symbolS *) obstack_alloc (¬es, sizeof (*def_symbol_in_progress));
  1971.   memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));
  1972.  
  1973.   symbol_name = input_line_pointer;
  1974.   name_end = get_symbol_end ();
  1975.   symbol_name_length = strlen (symbol_name);
  1976.   symbol_name_copy = xmalloc (symbol_name_length + 1);
  1977.   strcpy (symbol_name_copy, symbol_name);
  1978.  
  1979.   /* Initialize the new symbol */
  1980. #ifdef STRIP_UNDERSCORE
  1981.   S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
  1982.                        ? symbol_name_copy + 1
  1983.                        : symbol_name_copy));
  1984. #else /* STRIP_UNDERSCORE */
  1985.   S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
  1986. #endif /* STRIP_UNDERSCORE */
  1987.   /* free(symbol_name_copy); */
  1988.   def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;
  1989.   def_symbol_in_progress->sy_number = ~0;
  1990.   def_symbol_in_progress->sy_frag = &zero_address_frag;
  1991.   S_SET_VALUE (def_symbol_in_progress, 0);
  1992.  
  1993.   if (S_IS_STRING (def_symbol_in_progress))
  1994.     SF_SET_STRING (def_symbol_in_progress);
  1995.  
  1996.   *input_line_pointer = name_end;
  1997.  
  1998.   demand_empty_rest_of_line ();
  1999. }
  2000.  
  2001. unsigned int dim_index;
  2002.  
  2003.  
  2004. static void
  2005. obj_coff_endef (ignore)
  2006.      int ignore;
  2007. {
  2008.   symbolS *symbolP = 0;
  2009.   /* DIM BUG FIX sac@cygnus.com */
  2010.   dim_index = 0;
  2011.   if (def_symbol_in_progress == NULL)
  2012.     {
  2013.       as_warn (".endef pseudo-op used outside of .def/.endef: ignored.");
  2014.       demand_empty_rest_of_line ();
  2015.       return;
  2016.     }                /* if not inside .def/.endef */
  2017.  
  2018.   /* Set the section number according to storage class. */
  2019.   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
  2020.     {
  2021.     case C_STRTAG:
  2022.     case C_ENTAG:
  2023.     case C_UNTAG:
  2024.       SF_SET_TAG (def_symbol_in_progress);
  2025.       /* intentional fallthrough */
  2026.     case C_FILE:
  2027.     case C_TPDEF:
  2028.       SF_SET_DEBUG (def_symbol_in_progress);
  2029.       S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
  2030.       break;
  2031.  
  2032.     case C_EFCN:
  2033.       SF_SET_LOCAL (def_symbol_in_progress);    /* Do not emit this symbol. */
  2034.       /* intentional fallthrough */
  2035.     case C_BLOCK:
  2036.       SF_SET_PROCESS (def_symbol_in_progress);    /* Will need processing before writing */
  2037.       /* intentional fallthrough */
  2038.     case C_FCN:
  2039.       S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
  2040.  
  2041.       if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)
  2042.     {            /* .bf */
  2043.       if (function_lineoff < 0)
  2044.         {
  2045.           fprintf (stderr, "`.bf' symbol without preceding function\n");
  2046.         }            /* missing function symbol */
  2047.       SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
  2048.  
  2049.       SF_SET_PROCESS (last_line_symbol);
  2050.       function_lineoff = -1;
  2051.     }
  2052.       /* Value is always set to . */
  2053.       def_symbol_in_progress->sy_frag = frag_now;
  2054.       S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
  2055.       break;
  2056.  
  2057. #ifdef C_AUTOARG
  2058.     case C_AUTOARG:
  2059. #endif /* C_AUTOARG */
  2060.     case C_AUTO:
  2061.     case C_REG:
  2062.     case C_MOS:
  2063.     case C_MOE:
  2064.     case C_MOU:
  2065.     case C_ARG:
  2066.     case C_REGPARM:
  2067.     case C_FIELD:
  2068.     case C_EOS:
  2069.       SF_SET_DEBUG (def_symbol_in_progress);
  2070.       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
  2071.       break;
  2072.  
  2073.     case C_EXT:
  2074.     case C_STAT:
  2075.     case C_LABEL:
  2076.       /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
  2077.       break;
  2078.  
  2079.     case C_USTATIC:
  2080.     case C_EXTDEF:
  2081.     case C_ULABEL:
  2082.       as_warn ("unexpected storage class %d", S_GET_STORAGE_CLASS (def_symbol_in_progress));
  2083.       break;
  2084.     }                /* switch on storage class */
  2085.  
  2086.   /* Now that we have built a debug symbol, try to find if we should
  2087.      merge with an existing symbol or not.  If a symbol is C_EFCN or
  2088.      absolute_section or untagged SEG_DEBUG it never merges.  We also
  2089.      don't merge labels, which are in a different namespace, nor
  2090.      symbols which have not yet been defined since they are typically
  2091.      unique, nor do we merge tags with non-tags.  */
  2092.  
  2093.   /* Two cases for functions.  Either debug followed by definition or
  2094.      definition followed by debug.  For definition first, we will
  2095.      merge the debug symbol into the definition.  For debug first, the
  2096.      lineno entry MUST point to the definition function or else it
  2097.      will point off into space when crawl_symbols() merges the debug
  2098.      symbol into the real symbol.  Therefor, let's presume the debug
  2099.      symbol is a real function reference. */
  2100.  
  2101.   /* FIXME-SOON If for some reason the definition label/symbol is
  2102.      never seen, this will probably leave an undefined symbol at link
  2103.      time. */
  2104.  
  2105.   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
  2106.       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
  2107.       || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
  2108.       && !SF_GET_TAG (def_symbol_in_progress))
  2109.       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
  2110.       || def_symbol_in_progress->sy_value.X_op != O_constant
  2111.       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
  2112.       || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
  2113.     {
  2114.       symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
  2115.              &symbol_lastP);
  2116.     }
  2117.   else
  2118.     {
  2119.       /* This symbol already exists, merge the newly created symbol
  2120.      into the old one.  This is not mandatory. The linker can
  2121.      handle duplicate symbols correctly. But I guess that it save
  2122.      a *lot* of space if the assembly file defines a lot of
  2123.      symbols. [loic] */
  2124.  
  2125.       /* The debug entry (def_symbol_in_progress) is merged into the
  2126.      previous definition.  */
  2127.  
  2128.       c_symbol_merge (def_symbol_in_progress, symbolP);
  2129.       /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
  2130.       def_symbol_in_progress = symbolP;
  2131.  
  2132.       if (SF_GET_FUNCTION (def_symbol_in_progress)
  2133.       || SF_GET_TAG (def_symbol_in_progress))
  2134.     {
  2135.       /* For functions, and tags, the symbol *must* be where the
  2136.          debug symbol appears.  Move the existing symbol to the
  2137.          current place. */
  2138.       /* If it already is at the end of the symbol list, do nothing */
  2139.       if (def_symbol_in_progress != symbol_lastP)
  2140.         {
  2141.           symbol_remove (def_symbol_in_progress, &symbol_rootP,
  2142.                  &symbol_lastP);
  2143.           symbol_append (def_symbol_in_progress, symbol_lastP,
  2144.                  &symbol_rootP, &symbol_lastP);
  2145.         }            /* if not already in place */
  2146.     }            /* if function */
  2147.     }                /* normal or mergable */
  2148.  
  2149.   if (SF_GET_TAG (def_symbol_in_progress)
  2150.       && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL)
  2151.     {
  2152.       tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress);
  2153.     }
  2154.  
  2155.   if (SF_GET_FUNCTION (def_symbol_in_progress))
  2156.     {
  2157.       know (sizeof (def_symbol_in_progress) <= sizeof (long));
  2158.       function_lineoff
  2159.     = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
  2160.  
  2161.       SF_SET_PROCESS (def_symbol_in_progress);
  2162.  
  2163.       if (symbolP == NULL)
  2164.     {
  2165.       /* That is, if this is the first time we've seen the
  2166.          function... */
  2167.       symbol_table_insert (def_symbol_in_progress);
  2168.     }            /* definition follows debug */
  2169.     }                /* Create the line number entry pointing to the function being defined */
  2170.  
  2171.   def_symbol_in_progress = NULL;
  2172.   demand_empty_rest_of_line ();
  2173. }
  2174.  
  2175. static void
  2176. obj_coff_dim (ignore)
  2177.      int ignore;
  2178. {
  2179.   int dim_index;
  2180.  
  2181.   if (def_symbol_in_progress == NULL)
  2182.     {
  2183.       as_warn (".dim pseudo-op used outside of .def/.endef: ignored.");
  2184.       demand_empty_rest_of_line ();
  2185.       return;
  2186.     }                /* if not inside .def/.endef */
  2187.  
  2188.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  2189.  
  2190.   for (dim_index = 0; dim_index < DIMNUM; dim_index++)
  2191.     {
  2192.       SKIP_WHITESPACES ();
  2193.       SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
  2194.             get_absolute_expression ());
  2195.  
  2196.       switch (*input_line_pointer)
  2197.     {
  2198.     case ',':
  2199.       input_line_pointer++;
  2200.       break;
  2201.  
  2202.     default:
  2203.       as_warn ("badly formed .dim directive ignored");
  2204.       /* intentional fallthrough */
  2205.     case '\n':
  2206.     case ';':
  2207.       dim_index = DIMNUM;
  2208.       break;
  2209.     }
  2210.     }
  2211.  
  2212.   demand_empty_rest_of_line ();
  2213. }
  2214.  
  2215. static void
  2216. obj_coff_line (ignore)
  2217.      int ignore;
  2218. {
  2219.   int this_base;
  2220.   const char *name;
  2221.  
  2222.   if (def_symbol_in_progress == NULL)
  2223.     {
  2224.       obj_coff_ln (0);
  2225.       return;
  2226.     }
  2227.  
  2228.   name = S_GET_NAME (def_symbol_in_progress);
  2229.   this_base = get_absolute_expression ();
  2230.  
  2231.   /* Only .bf symbols indicate the use of a new base line number; the
  2232.      line numbers associated with .ef, .bb, .eb are relative to the
  2233.      start of the containing function.  */
  2234.   if (!strcmp (".bf", name))
  2235.     {
  2236. #if 0 /* XXX Can we ever have line numbers going backwards?  */
  2237.       if (this_base > line_base)
  2238. #endif
  2239.     {
  2240.       line_base = this_base;
  2241.     }
  2242.  
  2243. #ifndef NO_LISTING
  2244.       {
  2245.     extern int listing;
  2246.     if (listing && 0)
  2247.       {
  2248.         listing_source_line ((unsigned int) line_base);
  2249.       }
  2250.       }
  2251. #endif
  2252.     }
  2253.  
  2254.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  2255.   SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
  2256.  
  2257.   demand_empty_rest_of_line ();
  2258. }
  2259.  
  2260. static void
  2261. obj_coff_size (ignore)
  2262.      int ignore;
  2263. {
  2264.   if (def_symbol_in_progress == NULL)
  2265.     {
  2266.       as_warn (".size pseudo-op used outside of .def/.endef ignored.");
  2267.       demand_empty_rest_of_line ();
  2268.       return;
  2269.     }                /* if not inside .def/.endef */
  2270.  
  2271.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  2272.   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
  2273.   demand_empty_rest_of_line ();
  2274. }
  2275.  
  2276. static void
  2277. obj_coff_scl (ignore)
  2278.      int ignore;
  2279. {
  2280.   if (def_symbol_in_progress == NULL)
  2281.     {
  2282.       as_warn (".scl pseudo-op used outside of .def/.endef ignored.");
  2283.       demand_empty_rest_of_line ();
  2284.       return;
  2285.     }                /* if not inside .def/.endef */
  2286.  
  2287.   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
  2288.   demand_empty_rest_of_line ();
  2289. }
  2290.  
  2291. static void
  2292. obj_coff_tag (ignore)
  2293.      int ignore;
  2294. {
  2295.   char *symbol_name;
  2296.   char name_end;
  2297.  
  2298.   if (def_symbol_in_progress == NULL)
  2299.     {
  2300.       as_warn (".tag pseudo-op used outside of .def/.endef ignored.");
  2301.       demand_empty_rest_of_line ();
  2302.       return;
  2303.     }
  2304.  
  2305.   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
  2306.   symbol_name = input_line_pointer;
  2307.   name_end = get_symbol_end ();
  2308.  
  2309.   /* Assume that the symbol referred to by .tag is always defined.
  2310.      This was a bad assumption.  I've added find_or_make. xoxorich. */
  2311.   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
  2312.              (long) tag_find_or_make (symbol_name));
  2313.   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
  2314.     {
  2315.       as_warn ("tag not found for .tag %s", symbol_name);
  2316.     }                /* not defined */
  2317.  
  2318.   SF_SET_TAGGED (def_symbol_in_progress);
  2319.   *input_line_pointer = name_end;
  2320.  
  2321.   demand_empty_rest_of_line ();
  2322. }
  2323.  
  2324. static void
  2325. obj_coff_type (ignore)
  2326.      int ignore;
  2327. {
  2328.   if (def_symbol_in_progress == NULL)
  2329.     {
  2330.       as_warn (".type pseudo-op used outside of .def/.endef ignored.");
  2331.       demand_empty_rest_of_line ();
  2332.       return;
  2333.     }                /* if not inside .def/.endef */
  2334.  
  2335.   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
  2336.  
  2337.   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
  2338.       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
  2339.     {
  2340.       SF_SET_FUNCTION (def_symbol_in_progress);
  2341.     }                /* is a function */
  2342.  
  2343.   demand_empty_rest_of_line ();
  2344. }
  2345.  
  2346. static void
  2347. obj_coff_val (ignore)
  2348.      int ignore;
  2349. {
  2350.   if (def_symbol_in_progress == NULL)
  2351.     {
  2352.       as_warn (".val pseudo-op used outside of .def/.endef ignored.");
  2353.       demand_empty_rest_of_line ();
  2354.       return;
  2355.     }                /* if not inside .def/.endef */
  2356.  
  2357.   if (is_name_beginner (*input_line_pointer))
  2358.     {
  2359.       char *symbol_name = input_line_pointer;
  2360.       char name_end = get_symbol_end ();
  2361.  
  2362.       if (!strcmp (symbol_name, "."))
  2363.     {
  2364.       def_symbol_in_progress->sy_frag = frag_now;
  2365.       S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
  2366.       /* If the .val is != from the .def (e.g. statics) */
  2367.     }
  2368.       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
  2369.     {
  2370.       def_symbol_in_progress->sy_value.X_op = O_symbol;
  2371.       def_symbol_in_progress->sy_value.X_add_symbol =
  2372.         symbol_find_or_make (symbol_name);
  2373.       def_symbol_in_progress->sy_value.X_op_symbol = NULL;
  2374.       def_symbol_in_progress->sy_value.X_add_number = 0;
  2375.  
  2376.       /* If the segment is undefined when the forward reference is
  2377.          resolved, then copy the segment id from the forward
  2378.          symbol.  */
  2379.       SF_SET_GET_SEGMENT (def_symbol_in_progress);
  2380.  
  2381.       /* FIXME: gcc can generate address expressions
  2382.          here in unusual cases (search for "obscure"
  2383.          in sdbout.c).  We just ignore the offset
  2384.          here, thus generating incorrect debugging
  2385.          information.  We ignore the rest of the
  2386.          line just below.  */
  2387.     }
  2388.       /* Otherwise, it is the name of a non debug symbol and
  2389.      its value will be calculated later. */
  2390.       *input_line_pointer = name_end;
  2391.  
  2392.       /* FIXME: this is to avoid an error message in the
  2393.      FIXME case mentioned just above.  */
  2394.       while (! is_end_of_line[(unsigned char) *input_line_pointer])
  2395.     ++input_line_pointer;
  2396.     }
  2397.   else
  2398.     {
  2399.       S_SET_VALUE (def_symbol_in_progress,
  2400.            (valueT) get_absolute_expression ());
  2401.     }                /* if symbol based */
  2402.  
  2403.   demand_empty_rest_of_line ();
  2404. }
  2405.  
  2406. void
  2407. obj_read_begin_hook ()
  2408. {
  2409.   /* These had better be the same.  Usually 18 bytes. */
  2410. #ifndef BFD_HEADERS
  2411.   know (sizeof (SYMENT) == sizeof (AUXENT));
  2412.   know (SYMESZ == AUXESZ);
  2413. #endif
  2414.   tag_init ();
  2415. }
  2416.  
  2417. /* This function runs through the symbol table and puts all the
  2418.    externals onto another chain */
  2419.  
  2420. /* The chain of externals */
  2421. symbolS *symbol_externP;
  2422. symbolS *symbol_extern_lastP;
  2423.  
  2424. stack *block_stack;
  2425. symbolS *last_functionP;
  2426. symbolS *last_tagP;
  2427.  
  2428. static unsigned int
  2429. yank_symbols ()
  2430. {
  2431.   symbolS *symbolP;
  2432.   unsigned int symbol_number = 0;
  2433.   unsigned int last_file_symno = 0;
  2434.  
  2435.   for (symbolP = symbol_rootP;
  2436.        symbolP;
  2437.        symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
  2438.     {
  2439.       if (!SF_GET_DEBUG (symbolP))
  2440.     {
  2441.       /* Debug symbols do not need all this rubbish */
  2442.       symbolS *real_symbolP;
  2443.  
  2444.       /* L* and C_EFCN symbols never merge. */
  2445.       if (!SF_GET_LOCAL (symbolP)
  2446.           && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
  2447.           && symbolP->sy_value.X_op == O_constant
  2448.           && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
  2449.           && real_symbolP != symbolP)
  2450.         {
  2451.           /* FIXME-SOON: where do dups come from?
  2452.          Maybe tag references before definitions? xoxorich. */
  2453.           /* Move the debug data from the debug symbol to the
  2454.          real symbol. Do NOT do the oposite (i.e. move from
  2455.          real symbol to debug symbol and remove real symbol from the
  2456.          list.) Because some pointers refer to the real symbol
  2457.          whereas no pointers refer to the debug symbol. */
  2458.           c_symbol_merge (symbolP, real_symbolP);
  2459.           /* Replace the current symbol by the real one */
  2460.           /* The symbols will never be the last or the first
  2461.          because : 1st symbol is .file and 3 last symbols are
  2462.          .text, .data, .bss */
  2463.           symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
  2464.           symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
  2465.           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  2466.           symbolP = real_symbolP;
  2467.         }            /* if not local but dup'd */
  2468.  
  2469.       if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
  2470.         {
  2471.           S_SET_SEGMENT (symbolP, SEG_E0);
  2472.         }            /* push data into text */
  2473.  
  2474.       resolve_symbol_value (symbolP);
  2475.  
  2476.       if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
  2477.         {
  2478.           if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
  2479.         {
  2480.           S_SET_EXTERNAL (symbolP);
  2481.         }
  2482.           else if (S_GET_SEGMENT (symbolP) == SEG_E0)
  2483.         {
  2484.           S_SET_STORAGE_CLASS (symbolP, C_LABEL);
  2485.         }
  2486.           else
  2487.         {
  2488.           S_SET_STORAGE_CLASS (symbolP, C_STAT);
  2489.         }
  2490.         }
  2491.  
  2492.       /* Mainly to speed up if not -g */
  2493.       if (SF_GET_PROCESS (symbolP))
  2494.         {
  2495.           /* Handle the nested blocks auxiliary info. */
  2496.           if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
  2497.         {
  2498.           if (!strcmp (S_GET_NAME (symbolP), ".bb"))
  2499.             stack_push (block_stack, (char *) &symbolP);
  2500.           else
  2501.             {        /* .eb */
  2502.               register symbolS *begin_symbolP;
  2503.               begin_symbolP = *(symbolS **) stack_pop (block_stack);
  2504.               if (begin_symbolP == (symbolS *) 0)
  2505.             as_warn ("mismatched .eb");
  2506.               else
  2507.             SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
  2508.             }
  2509.         }
  2510.           /* If we are able to identify the type of a function, and we
  2511.            are out of a function (last_functionP == 0) then, the
  2512.            function symbol will be associated with an auxiliary
  2513.            entry. */
  2514.           if (last_functionP == (symbolS *) 0 &&
  2515.           SF_GET_FUNCTION (symbolP))
  2516.         {
  2517.           last_functionP = symbolP;
  2518.  
  2519.           if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
  2520.             {
  2521.               S_SET_NUMBER_AUXILIARY (symbolP, 1);
  2522.             }        /* make it at least 1 */
  2523.  
  2524.           /* Clobber possible stale .dim information. */
  2525. #if 0
  2526.           /* Iffed out by steve - this fries the lnnoptr info too */
  2527.           bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
  2528.              sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
  2529. #endif
  2530.         }
  2531.           /* The C_FCN doesn't need any additional information.  I
  2532.          don't even know if this is needed for sdb. But the
  2533.          standard assembler generates it, so...  */
  2534.           if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
  2535.         {
  2536.           if (last_functionP == (symbolS *) 0)
  2537.             as_fatal ("C_EFCN symbol out of scope");
  2538.           SA_SET_SYM_FSIZE (last_functionP,
  2539.                     (long) (S_GET_VALUE (symbolP) -
  2540.                         S_GET_VALUE (last_functionP)));
  2541.           SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
  2542.          last_functionP = (symbolS *) 0;
  2543.         }
  2544.         }
  2545.     }
  2546.       else if (SF_GET_TAG (symbolP))
  2547.     {
  2548.       /* First descriptor of a structure must point to
  2549.            the first slot after the structure description. */
  2550.       last_tagP = symbolP;
  2551.  
  2552.     }
  2553.       else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
  2554.     {
  2555.       /* +2 take in account the current symbol */
  2556.       SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
  2557.     }
  2558.       else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
  2559.     {
  2560.       if (S_GET_VALUE (symbolP))
  2561.         {
  2562.           S_SET_VALUE (symbolP, last_file_symno);
  2563.           last_file_symno = symbol_number;
  2564.         }            /* no one points at the first .file symbol */
  2565.     }            /* if debug or tag or eos or file */
  2566.  
  2567.       /* We must put the external symbols apart. The loader
  2568.      does not bomb if we do not. But the references in
  2569.      the endndx field for a .bb symbol are not corrected
  2570.      if an external symbol is removed between .bb and .be.
  2571.      I.e in the following case :
  2572.      [20] .bb endndx = 22
  2573.      [21] foo external
  2574.      [22] .be
  2575.      ld will move the symbol 21 to the end of the list but
  2576.      endndx will still be 22 instead of 21. */
  2577.  
  2578.  
  2579.       if (SF_GET_LOCAL (symbolP))
  2580.     {
  2581.       /* remove C_EFCN and LOCAL (L...) symbols */
  2582.       /* next pointer remains valid */
  2583.       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  2584.  
  2585.     }
  2586.       else if (!S_IS_DEFINED (symbolP)
  2587.            && !S_IS_DEBUG (symbolP)
  2588.            && !SF_GET_STATICS (symbolP) &&
  2589.            S_GET_STORAGE_CLASS (symbolP) == C_EXT)
  2590.     {            /* C_EXT && !SF_GET_FUNCTION(symbolP))  */
  2591.       /* if external, Remove from the list */
  2592.       symbolS *hold = symbol_previous (symbolP);
  2593.  
  2594.       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  2595.       symbol_clear_list_pointers (symbolP);
  2596.       symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
  2597.       symbolP = hold;
  2598.     }
  2599.       else
  2600.     {
  2601.       if (SF_GET_STRING (symbolP))
  2602.         {
  2603.           symbolP->sy_name_offset = string_byte_count;
  2604.           string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
  2605.         }
  2606.       else
  2607.         {
  2608.           symbolP->sy_name_offset = 0;
  2609.         }            /* fix "long" names */
  2610.  
  2611.       symbolP->sy_number = symbol_number;
  2612.       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
  2613.     }            /* if local symbol */
  2614.     }                /* traverse the symbol list */
  2615.   return symbol_number;
  2616.  
  2617. }
  2618.  
  2619.  
  2620. static unsigned int
  2621. glue_symbols ()
  2622. {
  2623.   unsigned int symbol_number = 0;
  2624.   symbolS *symbolP;
  2625.   for (symbolP = symbol_externP; symbol_externP;)
  2626.     {
  2627.       symbolS *tmp = symbol_externP;
  2628.  
  2629.       /* append */
  2630.       symbol_remove (tmp, &symbol_externP, &symbol_extern_lastP);
  2631.       symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
  2632.  
  2633.       /* and process */
  2634.       if (SF_GET_STRING (tmp))
  2635.     {
  2636.       tmp->sy_name_offset = string_byte_count;
  2637.       string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
  2638.     }
  2639.       else
  2640.     {
  2641.       tmp->sy_name_offset = 0;
  2642.     }            /* fix "long" names */
  2643.  
  2644.       tmp->sy_number = symbol_number;
  2645.       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
  2646.     }                /* append the entire extern chain */
  2647.   return symbol_number;
  2648.  
  2649. }
  2650.  
  2651. static unsigned int
  2652. tie_tags ()
  2653. {
  2654.   unsigned int symbol_number = 0;
  2655.  
  2656.   symbolS *symbolP;
  2657.   for (symbolP = symbol_rootP; symbolP; symbolP =
  2658.        symbol_next (symbolP))
  2659.     {
  2660.       symbolP->sy_number = symbol_number;
  2661.  
  2662.  
  2663.  
  2664.       if (SF_GET_TAGGED (symbolP))
  2665.     {
  2666.       SA_SET_SYM_TAGNDX
  2667.         (symbolP,
  2668.          ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
  2669.     }
  2670.  
  2671.       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
  2672.     }
  2673.   return symbol_number;
  2674.  
  2675. }
  2676.  
  2677. static void
  2678. crawl_symbols (h, abfd)
  2679.      object_headers *h;
  2680.      bfd * abfd;
  2681. {
  2682.   unsigned int i;
  2683.  
  2684.   /* Initialize the stack used to keep track of the matching .bb .be */
  2685.  
  2686.   block_stack = stack_init (512, sizeof (symbolS *));
  2687.  
  2688.   /* The symbol list should be ordered according to the following sequence
  2689.    * order :
  2690.    * . .file symbol
  2691.    * . debug entries for functions
  2692.    * . fake symbols for the sections, including.text .data and .bss
  2693.    * . defined symbols
  2694.    * . undefined symbols
  2695.    * But this is not mandatory. The only important point is to put the
  2696.    * undefined symbols at the end of the list.
  2697.    */
  2698.  
  2699.   if (symbol_rootP == NULL
  2700.       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
  2701.     {
  2702.       c_dot_file_symbol ("fake");
  2703.     }
  2704.   /* Is there a .file symbol ? If not insert one at the beginning. */
  2705.  
  2706.   /*
  2707.    * Build up static symbols for the sections, they are filled in later
  2708.    */
  2709.  
  2710.  
  2711.   for (i = SEG_E0; i < SEG_E9; i++)
  2712.     {
  2713.       if (segment_info[i].scnhdr.s_name[0])
  2714.     {
  2715.       char name[9];
  2716.  
  2717.       strncpy (name, segment_info[i].scnhdr.s_name, 8);
  2718.       name[8] = '\0';
  2719.       segment_info[i].dot = c_section_symbol (name, i - SEG_E0 + 1);
  2720.     }
  2721.     }
  2722.  
  2723.  
  2724.   /* Take all the externals out and put them into another chain */
  2725.   H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
  2726.   /* Take the externals and glue them onto the end.*/
  2727.   H_SET_SYMBOL_TABLE_SIZE (h, H_GET_SYMBOL_COUNT (h) + glue_symbols ());
  2728.  
  2729.   H_SET_SYMBOL_TABLE_SIZE (h, tie_tags ());
  2730.   know (symbol_externP == NULL);
  2731.   know (symbol_extern_lastP == NULL);
  2732. }
  2733.  
  2734. /*
  2735.  * Find strings by crawling along symbol table chain.
  2736.  */
  2737.  
  2738. void
  2739. w_strings (where)
  2740.      char *where;
  2741. {
  2742.   symbolS *symbolP;
  2743.  
  2744.   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
  2745.   md_number_to_chars (where, (valueT) string_byte_count, 4);
  2746.   where += 4;
  2747.   for (symbolP = symbol_rootP;
  2748.        symbolP;
  2749.        symbolP = symbol_next (symbolP))
  2750.     {
  2751.       unsigned int size;
  2752.  
  2753.       if (SF_GET_STRING (symbolP))
  2754.     {
  2755.       size = strlen (S_GET_NAME (symbolP)) + 1;
  2756.  
  2757.       memcpy (where, S_GET_NAME (symbolP), size);
  2758.       where += size;
  2759.  
  2760.     }
  2761.     }
  2762. }
  2763.  
  2764. static void
  2765. do_linenos_for (abfd, h, file_cursor)
  2766.      bfd * abfd;
  2767.      object_headers * h;
  2768.      unsigned long *file_cursor;
  2769. {
  2770.   unsigned int idx;
  2771.   unsigned long start = *file_cursor;
  2772.  
  2773.   for (idx = SEG_E0; idx < SEG_E9; idx++)
  2774.     {
  2775.       segment_info_type *s = segment_info + idx;
  2776.  
  2777.  
  2778.       if (s->scnhdr.s_nlnno != 0)
  2779.     {
  2780.       struct lineno_list *line_ptr;
  2781.  
  2782.       struct external_lineno *buffer =
  2783.       (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
  2784.  
  2785.       struct external_lineno *dst = buffer;
  2786.  
  2787.       /* Run through the table we've built and turn it into its external
  2788.      form, take this chance to remove duplicates */
  2789.  
  2790.       for (line_ptr = s->lineno_list_head;
  2791.            line_ptr != (struct lineno_list *) NULL;
  2792.            line_ptr = line_ptr->next)
  2793.         {
  2794.  
  2795.           if (line_ptr->line.l_lnno == 0)
  2796.         {
  2797.           /* Turn a pointer to a symbol into the symbols' index */
  2798.           line_ptr->line.l_addr.l_symndx =
  2799.             ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
  2800.         }
  2801.           else
  2802.         {
  2803.           line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
  2804.         }
  2805.  
  2806.  
  2807.           (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
  2808.           dst++;
  2809.  
  2810.         }
  2811.  
  2812.       s->scnhdr.s_lnnoptr = *file_cursor;
  2813.  
  2814.       bfd_write (buffer, 1, s->scnhdr.s_nlnno * LINESZ, abfd);
  2815.       free (buffer);
  2816.  
  2817.       *file_cursor += s->scnhdr.s_nlnno * LINESZ;
  2818.     }
  2819.     }
  2820.   H_SET_LINENO_SIZE (h, *file_cursor - start);
  2821. }
  2822.  
  2823.  
  2824. /* Now we run through the list of frag chains in a segment and
  2825.    make all the subsegment frags appear at the end of the
  2826.    list, as if the seg 0 was extra long */
  2827.  
  2828. static void
  2829. remove_subsegs ()
  2830. {
  2831.   unsigned int i;
  2832.  
  2833.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  2834.     {
  2835.       frchainS *head = segment_info[i].frchainP;
  2836.       fragS dummy;
  2837.       fragS *prev_frag = &dummy;
  2838.  
  2839.       while (head && head->frch_seg == i)
  2840.     {
  2841.       prev_frag->fr_next = head->frch_root;
  2842.       prev_frag = head->frch_last;
  2843.       head = head->frch_next;
  2844.     }
  2845.       prev_frag->fr_next = 0;
  2846.     }
  2847. }
  2848.  
  2849. unsigned long machine;
  2850. int coff_flags;
  2851. extern void
  2852. write_object_file ()
  2853. {
  2854.   int i;
  2855.   char *name;
  2856.   struct frchain *frchain_ptr;
  2857.  
  2858.   object_headers headers;
  2859.   unsigned long file_cursor;
  2860.   bfd *abfd;
  2861.   unsigned int addr;
  2862.   abfd = bfd_openw (out_file_name, TARGET_FORMAT);
  2863.  
  2864.  
  2865.   if (abfd == 0)
  2866.     {
  2867.       as_perror ("FATAL: Can't create %s", out_file_name);
  2868.       exit (EXIT_FAILURE);
  2869.     }
  2870.   bfd_set_format (abfd, bfd_object);
  2871.   bfd_set_arch_mach (abfd, BFD_ARCH, machine);
  2872.  
  2873.   string_byte_count = 4;
  2874.  
  2875.   for (frchain_ptr = frchain_root;
  2876.        frchain_ptr != (struct frchain *) NULL;
  2877.        frchain_ptr = frchain_ptr->frch_next)
  2878.     {
  2879.       /* Run through all the sub-segments and align them up.  Also
  2880.      close any open frags.  We tack a .fill onto the end of the
  2881.      frag chain so that any .align's size can be worked by looking
  2882.      at the next frag.  */
  2883.  
  2884.       subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
  2885. #ifndef SUB_SEGMENT_ALIGN
  2886. #define SUB_SEGMENT_ALIGN(SEG) 1
  2887. #endif
  2888.       frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE);
  2889.       frag_wane (frag_now);
  2890.       frag_now->fr_fix = 0;
  2891.       know (frag_now->fr_next == NULL);
  2892.     }
  2893.  
  2894.  
  2895.   remove_subsegs ();
  2896.  
  2897.  
  2898.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  2899.     {
  2900.       relax_segment (segment_info[i].frchainP->frch_root, i);
  2901.     }
  2902.  
  2903.   H_SET_NUMBER_OF_SECTIONS (&headers, 0);
  2904.  
  2905.   /* Find out how big the sections are, and set the addresses.  */
  2906.   addr = 0;
  2907.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  2908.     {
  2909.       long size;
  2910.  
  2911.       segment_info[i].scnhdr.s_paddr = addr;
  2912.       segment_info[i].scnhdr.s_vaddr = addr;
  2913.  
  2914.       if (segment_info[i].scnhdr.s_name[0])
  2915.     {
  2916.       H_SET_NUMBER_OF_SECTIONS (&headers,
  2917.                     H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
  2918.     }
  2919.  
  2920.       size = size_section (abfd, (unsigned int) i);
  2921.       addr += size;
  2922.  
  2923.       /* I think the section alignment is only used on the i960; the
  2924.      i960 needs it, and it should do no harm on other targets.  */
  2925.       segment_info[i].scnhdr.s_align = section_alignment[i];
  2926.  
  2927.       if (i == SEG_E0)
  2928.     H_SET_TEXT_SIZE (&headers, size);
  2929.       else if (i == SEG_E1)
  2930.     H_SET_DATA_SIZE (&headers, size);
  2931.       else if (i == SEG_E2)
  2932.     H_SET_BSS_SIZE (&headers, size);
  2933.     }
  2934.  
  2935.   /* Turn the gas native symbol table shape into a coff symbol table */
  2936.   crawl_symbols (&headers, abfd);
  2937.  
  2938.   if (string_byte_count == 4)
  2939.     string_byte_count = 0;
  2940.  
  2941.   H_SET_STRING_SIZE (&headers, string_byte_count);
  2942.  
  2943. #if !defined(TC_H8300) && !defined(TC_Z8K)
  2944.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  2945.     {
  2946.       fixup_mdeps (segment_info[i].frchainP->frch_root, &headers, i);
  2947.       fixup_segment (&segment_info[i], i);
  2948.     }
  2949. #endif
  2950.  
  2951.   /* Look for ".stab" segments and fill in their initial symbols
  2952.      correctly. */
  2953.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  2954.     {
  2955.       name = segment_info[i].scnhdr.s_name;
  2956.  
  2957.       if (name != NULL
  2958.       && strncmp (".stab", name, 5) == 0
  2959.       && strncmp (".stabstr", name, 8) != 0)
  2960.     adjust_stab_section (abfd, i);
  2961.     }
  2962.  
  2963.   file_cursor = H_GET_TEXT_FILE_OFFSET (&headers);
  2964.  
  2965.   bfd_seek (abfd, (file_ptr) file_cursor, 0);
  2966.  
  2967.   /* Plant the data */
  2968.  
  2969.   fill_section (abfd, &headers, &file_cursor);
  2970.  
  2971.   do_relocs_for (abfd, &headers, &file_cursor);
  2972.  
  2973.   do_linenos_for (abfd, &headers, &file_cursor);
  2974.  
  2975.   H_SET_FILE_MAGIC_NUMBER (&headers, COFF_MAGIC);
  2976. #ifndef OBJ_COFF_OMIT_TIMESTAMP
  2977.   H_SET_TIME_STAMP (&headers, (long)time((long*)0));
  2978. #else
  2979.   H_SET_TIME_STAMP (&headers, 0);
  2980. #endif
  2981. #ifdef TC_COFF_SET_MACHINE
  2982.   TC_COFF_SET_MACHINE (&headers);
  2983. #endif
  2984.  
  2985. #ifdef KEEP_RELOC_INFO
  2986.   H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
  2987.               COFF_FLAGS | coff_flags));
  2988. #else
  2989.   H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers)     ? 0 : F_LNNO)   |
  2990.               (H_GET_RELOCATION_SIZE(&headers) ? 0 : F_RELFLG) |
  2991.               COFF_FLAGS | coff_flags));
  2992. #endif
  2993.  
  2994.   {
  2995.     unsigned int symtable_size = H_GET_SYMBOL_TABLE_SIZE (&headers);
  2996.     char *buffer1 = xmalloc (symtable_size + string_byte_count + 1);
  2997.  
  2998.     H_SET_SYMBOL_TABLE_POINTER (&headers, bfd_tell (abfd));
  2999.     w_symbols (abfd, buffer1, symbol_rootP);
  3000.     if (string_byte_count > 0)
  3001.       w_strings (buffer1 + symtable_size);
  3002.     bfd_write (buffer1, 1, symtable_size + string_byte_count, abfd);
  3003.     free (buffer1);
  3004.   }
  3005.  
  3006.   coff_header_append (abfd, &headers);
  3007. #if 0
  3008.   /* Recent changes to write need this, but where it should
  3009.      go is up to Ken.. */
  3010.   if (bfd_close_all_done (abfd) == false)
  3011.     as_fatal ("Can't close %s: %s", out_file_name,
  3012.           bfd_errmsg (bfd_get_error ()));
  3013. #else
  3014.   {
  3015.     extern bfd *stdoutput;
  3016.     stdoutput = abfd;
  3017.   }
  3018. #endif
  3019.  
  3020. }
  3021.  
  3022. /* Add a new segment.  This is called from subseg_new via the
  3023.    obj_new_segment macro.  */
  3024.  
  3025. segT
  3026. obj_coff_add_segment (name)
  3027.      const char *name;
  3028. {
  3029.   unsigned int len;
  3030.   unsigned int i;
  3031.  
  3032.   /* Find out if we've already got a section of this name.  */
  3033.   len = strlen (name);
  3034.   if (len < sizeof (segment_info[i].scnhdr.s_name))
  3035.     ++len;
  3036.   else
  3037.     len = sizeof (segment_info[i].scnhdr.s_name);
  3038.   for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++)
  3039.     if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0
  3040.     && (len == sizeof (segment_info[i].scnhdr.s_name)
  3041.         || segment_info[i].scnhdr.s_name[len] == '\0'))
  3042.       return (segT) i;
  3043.  
  3044.   if (i == SEG_E9)
  3045.     {
  3046.       as_bad ("Too many new sections; can't add \"%s\"", name);
  3047.       return now_seg;
  3048.     }
  3049.  
  3050.   /* Add a new section.  */
  3051.   strncpy (segment_info[i].scnhdr.s_name, name,
  3052.        sizeof (segment_info[i].scnhdr.s_name));
  3053.   segment_info[i].scnhdr.s_flags = STYP_REG;
  3054.  
  3055.   return (segT) i;
  3056. }
  3057.  
  3058. /*
  3059.  * implement the .section pseudo op:
  3060.  *    .section name {, "flags"}
  3061.  *                ^         ^
  3062.  *                |         +--- optional flags: 'b' for bss
  3063.  *                |                              'i' for info
  3064.  *                +-- section name               'l' for lib
  3065.  *                                               'n' for noload
  3066.  *                                               'o' for over
  3067.  *                                               'w' for data
  3068.  *                         'd' (apparently m88k for data)
  3069.  *                                               'x' for text
  3070.  * But if the argument is not a quoted string, treat it as a
  3071.  * subsegment number.
  3072.  */
  3073.  
  3074. void
  3075. obj_coff_section (ignore)
  3076.      int ignore;
  3077. {
  3078.   /* Strip out the section name */
  3079.   char *section_name;
  3080.   char *section_name_end;
  3081.   char c;
  3082.   int argp;
  3083.   unsigned int len;
  3084.   unsigned int exp;
  3085.   long flags;
  3086.  
  3087.   section_name = input_line_pointer;
  3088.   c = get_symbol_end ();
  3089.   section_name_end = input_line_pointer;
  3090.  
  3091.   len = section_name_end - section_name;
  3092.   input_line_pointer++;
  3093.   SKIP_WHITESPACE ();
  3094.  
  3095.   argp = 0;
  3096.   if (c == ',')
  3097.     argp = 1;
  3098.   else if (*input_line_pointer == ',')
  3099.     {
  3100.       argp = 1;
  3101.       ++input_line_pointer;
  3102.       SKIP_WHITESPACE ();
  3103.     }
  3104.  
  3105.   exp = 0;
  3106.   flags = 0;
  3107.   if (argp)
  3108.     {
  3109.       if (*input_line_pointer != '"')
  3110.     exp = get_absolute_expression ();
  3111.       else
  3112.     {
  3113.       ++input_line_pointer;
  3114.       while (*input_line_pointer != '"'
  3115.          && ! is_end_of_line[(unsigned char) *input_line_pointer])
  3116.         {
  3117.           switch (*input_line_pointer)
  3118.         {
  3119.         case 'b': flags |= STYP_BSS;    break;
  3120.         case 'i': flags |= STYP_INFO;   break;
  3121.         case 'l': flags |= STYP_LIB;    break;
  3122.         case 'n': flags |= STYP_NOLOAD; break;
  3123.         case 'o': flags |= STYP_OVER;   break;
  3124.         case 'd':
  3125.         case 'w': flags |= STYP_DATA;   break;
  3126.         case 'x': flags |= STYP_TEXT;   break;
  3127.         default:
  3128.           as_warn("unknown section attribute '%c'",
  3129.               *input_line_pointer);
  3130.           break;
  3131.         }
  3132.           ++input_line_pointer;
  3133.         }
  3134.       if (*input_line_pointer == '"')
  3135.         ++input_line_pointer;
  3136.     }
  3137.     }
  3138.  
  3139.   subseg_new (section_name, (subsegT) exp);
  3140.  
  3141.   segment_info[now_seg].scnhdr.s_flags |= flags;
  3142.  
  3143.   *section_name_end = c;
  3144. }
  3145.  
  3146.  
  3147. static void
  3148. obj_coff_text (ignore)
  3149.      int ignore;
  3150. {
  3151.   subseg_new (".text", get_absolute_expression ());
  3152. }
  3153.  
  3154.  
  3155. static void
  3156. obj_coff_data (ignore)
  3157.      int ignore;
  3158. {
  3159.   if (flag_readonly_data_in_text)
  3160.     subseg_new (".text", get_absolute_expression () + 1000);
  3161.   else
  3162.     subseg_new (".data", get_absolute_expression ());
  3163. }
  3164.  
  3165. static void
  3166. obj_coff_bss (ignore)
  3167.      int ignore;
  3168. {
  3169.   if (*input_line_pointer == '\n')    /* .bss         */
  3170.     subseg_new(".bss", get_absolute_expression());
  3171.   else                    /* .bss id,expr        */
  3172.     obj_coff_lcomm(0);
  3173. }
  3174.  
  3175. static void
  3176. obj_coff_ident (ignore)
  3177.      int ignore;
  3178. {
  3179.   segT current_seg = now_seg;        /* save current seg    */
  3180.   subsegT current_subseg = now_subseg;
  3181.   subseg_new (".comment", 0);        /* .comment seg        */
  3182.   stringer (1);                /* read string        */
  3183.   subseg_set (current_seg, current_subseg);    /* restore current seg    */
  3184. }
  3185.  
  3186. void
  3187. c_symbol_merge (debug, normal)
  3188.      symbolS *debug;
  3189.      symbolS *normal;
  3190. {
  3191.   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
  3192.   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
  3193.  
  3194.   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
  3195.     {
  3196.       S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
  3197.     }                /* take the most we have */
  3198.  
  3199.   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
  3200.     {
  3201.       memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
  3202.           (char *) &debug->sy_symbol.ost_auxent[0],
  3203.           (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ));
  3204.     }                /* Move all the auxiliary information */
  3205.  
  3206.   /* Move the debug flags. */
  3207.   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
  3208. }                /* c_symbol_merge() */
  3209.  
  3210. static int
  3211. c_line_new (symbol, paddr, line_number, frag)
  3212.      symbolS * symbol;
  3213.      long paddr;
  3214.      int line_number;
  3215.      fragS * frag;
  3216. {
  3217.   struct lineno_list *new_line =
  3218.   (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
  3219.  
  3220.   segment_info_type *s = segment_info + now_seg;
  3221.   new_line->line.l_lnno = line_number;
  3222.  
  3223.   if (line_number == 0)
  3224.     {
  3225.       last_line_symbol = symbol;
  3226.       new_line->line.l_addr.l_symndx = (long) symbol;
  3227.     }
  3228.   else
  3229.     {
  3230.       new_line->line.l_addr.l_paddr = paddr;
  3231.     }
  3232.  
  3233.   new_line->frag = (char *) frag;
  3234.   new_line->next = (struct lineno_list *) NULL;
  3235.  
  3236.  
  3237.   if (s->lineno_list_head == (struct lineno_list *) NULL)
  3238.     {
  3239.       s->lineno_list_head = new_line;
  3240.     }
  3241.   else
  3242.     {
  3243.       s->lineno_list_tail->next = new_line;
  3244.     }
  3245.   s->lineno_list_tail = new_line;
  3246.   return LINESZ * s->scnhdr.s_nlnno++;
  3247. }
  3248.  
  3249. void
  3250. c_dot_file_symbol (filename)
  3251.      char *filename;
  3252. {
  3253.   symbolS *symbolP;
  3254.  
  3255.   symbolP = symbol_new (".file",
  3256.             SEG_DEBUG,
  3257.             0,
  3258.             &zero_address_frag);
  3259.  
  3260.   S_SET_STORAGE_CLASS (symbolP, C_FILE);
  3261.   S_SET_NUMBER_AUXILIARY (symbolP, 1);
  3262.   SA_SET_FILE_FNAME (symbolP, filename);
  3263. #ifndef NO_LISTING
  3264.   {
  3265.     extern int listing;
  3266.     if (listing)
  3267.       {
  3268.     listing_source_file (filename);
  3269.       }
  3270.  
  3271.   }
  3272.  
  3273. #endif
  3274.   SF_SET_DEBUG (symbolP);
  3275.   S_SET_VALUE (symbolP, (valueT) previous_file_symbol);
  3276.  
  3277.   previous_file_symbol = symbolP;
  3278.  
  3279.   /* Make sure that the symbol is first on the symbol chain */
  3280.   if (symbol_rootP != symbolP)
  3281.     {
  3282.       if (symbolP == symbol_lastP)
  3283.     {
  3284.       symbol_lastP = symbol_lastP->sy_previous;
  3285.     }            /* if it was the last thing on the list */
  3286.  
  3287.       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
  3288.       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
  3289.       symbol_rootP = symbolP;
  3290.     }                /* if not first on the list */
  3291.  
  3292. }                /* c_dot_file_symbol() */
  3293.  
  3294. /*
  3295.  * Build a 'section static' symbol.
  3296.  */
  3297.  
  3298. symbolS *
  3299. c_section_symbol (name, idx)
  3300.      char *name;
  3301.      int idx;
  3302. {
  3303.   symbolS *symbolP;
  3304.  
  3305.   symbolP = symbol_new (name, idx,
  3306.             0,
  3307.             &zero_address_frag);
  3308.  
  3309.   S_SET_STORAGE_CLASS (symbolP, C_STAT);
  3310.   S_SET_NUMBER_AUXILIARY (symbolP, 1);
  3311.  
  3312.   SF_SET_STATICS (symbolP);
  3313.  
  3314.   return symbolP;
  3315. }                /* c_section_symbol() */
  3316.  
  3317. static void
  3318. w_symbols (abfd, where, symbol_rootP)
  3319.      bfd * abfd;
  3320.      char *where;
  3321.      symbolS * symbol_rootP;
  3322. {
  3323.   symbolS *symbolP;
  3324.   unsigned int i;
  3325.  
  3326.   /* First fill in those values we have only just worked out */
  3327.   for (i = SEG_E0; i < SEG_E9; i++)
  3328.     {
  3329.       symbolP = segment_info[i].dot;
  3330.       if (symbolP)
  3331.     {
  3332.       SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
  3333.       SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
  3334.       SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
  3335.     }
  3336.     }
  3337.  
  3338.   /*
  3339.      * Emit all symbols left in the symbol chain.
  3340.      */
  3341.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  3342.     {
  3343.       /* Used to save the offset of the name. It is used to point
  3344.            to the string in memory but must be a file offset. */
  3345.       register char *temp;
  3346.  
  3347.       tc_coff_symbol_emit_hook (symbolP);
  3348.  
  3349.       temp = S_GET_NAME (symbolP);
  3350.       if (SF_GET_STRING (symbolP))
  3351.     {
  3352.       S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
  3353.       S_SET_ZEROES (symbolP, 0);
  3354.     }
  3355.       else
  3356.     {
  3357.       memset (symbolP->sy_symbol.ost_entry.n_name, 0, SYMNMLEN);
  3358.       strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
  3359.     }
  3360.       where = symbol_to_chars (abfd, where, symbolP);
  3361.       S_SET_NAME (symbolP, temp);
  3362.     }
  3363.  
  3364. }                /* w_symbols() */
  3365.  
  3366. static void
  3367. obj_coff_lcomm (ignore)
  3368.      int ignore;
  3369. {
  3370.   s_lcomm(0);
  3371.   return;
  3372. #if 0
  3373.   char *name;
  3374.   char c;
  3375.   int temp;
  3376.   char *p;
  3377.  
  3378.   symbolS *symbolP;
  3379.  
  3380.   name = input_line_pointer;
  3381.  
  3382.   c = get_symbol_end ();
  3383.   p = input_line_pointer;
  3384.   *p = c;
  3385.   SKIP_WHITESPACE ();
  3386.   if (*input_line_pointer != ',')
  3387.     {
  3388.       as_bad ("Expected comma after name");
  3389.       ignore_rest_of_line ();
  3390.       return;
  3391.     }
  3392.   if (*input_line_pointer == '\n')
  3393.     {
  3394.       as_bad ("Missing size expression");
  3395.       return;
  3396.     }
  3397.   input_line_pointer++;
  3398.   if ((temp = get_absolute_expression ()) < 0)
  3399.     {
  3400.       as_warn ("lcomm length (%d.) <0! Ignored.", temp);
  3401.       ignore_rest_of_line ();
  3402.       return;
  3403.     }
  3404.   *p = 0;
  3405.  
  3406.   symbolP = symbol_find_or_make(name);
  3407.  
  3408.   if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN &&
  3409.       S_GET_VALUE(symbolP) == 0)
  3410.     {
  3411.       if (! need_pass_2)
  3412.     {
  3413.       char *p;
  3414.       segT current_seg = now_seg;     /* save current seg     */
  3415.       subsegT current_subseg = now_subseg;
  3416.  
  3417.       subseg_set (SEG_E2, 1);
  3418.       symbolP->sy_frag = frag_now;
  3419.       p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
  3420.                temp, (char *)0);
  3421.       *p = 0;
  3422.       subseg_set (current_seg, current_subseg); /* restore current seg */
  3423.       S_SET_SEGMENT(symbolP, SEG_E2);
  3424.       S_SET_STORAGE_CLASS(symbolP, C_STAT);
  3425.     }
  3426.     }
  3427.   else
  3428.     as_bad("Symbol %s already defined", name);
  3429.  
  3430.   demand_empty_rest_of_line();
  3431. #endif
  3432. }
  3433.  
  3434. static void
  3435. fixup_mdeps (frags, h, this_segment)
  3436.      fragS * frags;
  3437.      object_headers * h;
  3438.      segT this_segment;
  3439. {
  3440.   subseg_change (this_segment, 0);
  3441.   while (frags)
  3442.     {
  3443.       switch (frags->fr_type)
  3444.     {
  3445.     case rs_align:
  3446.     case rs_org:
  3447.       frags->fr_type = rs_fill;
  3448.       frags->fr_offset =
  3449.         (frags->fr_next->fr_address - frags->fr_address - frags->fr_fix);
  3450.       break;
  3451.     case rs_machine_dependent:
  3452.       md_convert_frag (h, frags);
  3453.       frag_wane (frags);
  3454.       break;
  3455.     default:
  3456.       ;
  3457.     }
  3458.       frags = frags->fr_next;
  3459.     }
  3460. }
  3461.  
  3462. #if 1
  3463. static void
  3464. fixup_segment (segP, this_segment_type)
  3465.      segment_info_type * segP;
  3466.      segT this_segment_type;
  3467. {
  3468.   register fixS * fixP;
  3469.   register symbolS *add_symbolP;
  3470.   register symbolS *sub_symbolP;
  3471.   register long add_number;
  3472.   register int size;
  3473.   register char *place;
  3474.   register long where;
  3475.   register char pcrel;
  3476.   register fragS *fragP;
  3477.   register segT add_symbol_segment = absolute_section;
  3478.  
  3479.  
  3480.   for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
  3481.     {
  3482.       fragP = fixP->fx_frag;
  3483.       know (fragP);
  3484.       where = fixP->fx_where;
  3485.       place = fragP->fr_literal + where;
  3486.       size = fixP->fx_size;
  3487.       add_symbolP = fixP->fx_addsy;
  3488. #ifdef TC_I960
  3489.       if (fixP->fx_tcbit && SF_GET_CALLNAME (add_symbolP))
  3490.     {
  3491.       /* Relocation should be done via the associated 'bal' entry
  3492.          point symbol. */
  3493.  
  3494.       if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
  3495.         {
  3496.           as_bad_where (fixP->fx_file, fixP->fx_line,
  3497.                 "No 'bal' entry point for leafproc %s",
  3498.                 S_GET_NAME (add_symbolP));
  3499.           continue;
  3500.         }
  3501.       fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
  3502.     }
  3503. #endif
  3504.       sub_symbolP = fixP->fx_subsy;
  3505.       add_number = fixP->fx_offset;
  3506.       pcrel = fixP->fx_pcrel;
  3507.  
  3508.       if (add_symbolP)
  3509.     {
  3510.       add_symbol_segment = S_GET_SEGMENT (add_symbolP);
  3511.     }            /* if there is an addend */
  3512.  
  3513.       if (sub_symbolP)
  3514.     {
  3515.       if (!add_symbolP)
  3516.         {
  3517.           /* Its just -sym */
  3518.           if (S_GET_SEGMENT (sub_symbolP) != absolute_section)
  3519.         {
  3520.           as_bad_where (fixP->fx_file, fixP->fx_line,
  3521.                 "Negative of non-absolute symbol %s",
  3522.                 S_GET_NAME (sub_symbolP));
  3523.         }        /* not absolute */
  3524.  
  3525.           add_number -= S_GET_VALUE (sub_symbolP);
  3526.           fixP->fx_subsy = 0;
  3527.  
  3528.           /* if sub_symbol is in the same segment that add_symbol
  3529.                and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
  3530.         }
  3531.       else if ((S_GET_SEGMENT (sub_symbolP) == add_symbol_segment)
  3532.            && (SEG_NORMAL (add_symbol_segment)
  3533.                || (add_symbol_segment == absolute_section)))
  3534.         {
  3535.           /* Difference of 2 symbols from same segment.  Can't
  3536.          make difference of 2 undefineds: 'value' means
  3537.          something different for N_UNDF. */
  3538. #ifdef TC_I960
  3539.           /* Makes no sense to use the difference of 2 arbitrary symbols
  3540.              as the target of a call instruction.  */
  3541.           if (fixP->fx_tcbit)
  3542.         {
  3543.           as_bad_where (fixP->fx_file, fixP->fx_line,
  3544.                 "callj to difference of 2 symbols");
  3545.         }
  3546. #endif /* TC_I960 */
  3547.           add_number += S_GET_VALUE (add_symbolP) -
  3548.         S_GET_VALUE (sub_symbolP);
  3549.  
  3550.           add_symbolP = NULL;
  3551.           fixP->fx_addsy = NULL;
  3552.           fixP->fx_subsy = NULL;
  3553.           fixP->fx_done = 1;
  3554.         }
  3555.       else
  3556.         {
  3557.           /* Different segments in subtraction. */
  3558.           know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
  3559.  
  3560.           if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
  3561.         {
  3562.           add_number -= S_GET_VALUE (sub_symbolP);
  3563.         }
  3564. #ifdef DIFF_EXPR_OK
  3565.           else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
  3566. #if 0 /* Okay for 68k, at least... */
  3567.                && !pcrel
  3568. #endif
  3569.                )
  3570.         {
  3571.           /* Make it pc-relative.  */
  3572.           add_number += (md_pcrel_from (fixP)
  3573.                  - S_GET_VALUE (sub_symbolP));
  3574.           pcrel = 1;
  3575.           fixP->fx_pcrel = 1;
  3576.           sub_symbolP = 0;
  3577.           fixP->fx_subsy = 0;
  3578.         }
  3579. #endif
  3580.           else
  3581.         {
  3582.           as_bad_where (fixP->fx_file, fixP->fx_line,
  3583.                 "Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld.",
  3584.                 segment_name (S_GET_SEGMENT (sub_symbolP)),
  3585.                 S_GET_NAME (sub_symbolP),
  3586.                 (long) (fragP->fr_address + where));
  3587.         }        /* if absolute */
  3588.         }
  3589.     }            /* if sub_symbolP */
  3590.  
  3591.       if (add_symbolP)
  3592.     {
  3593.       if (add_symbol_segment == this_segment_type && pcrel)
  3594.         {
  3595.           /*
  3596.            * This fixup was made when the symbol's segment was
  3597.            * SEG_UNKNOWN, but it is now in the local segment.
  3598.            * So we know how to do the address without relocation.
  3599.            */
  3600. #ifdef TC_I960
  3601.           /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
  3602.            * in which cases it modifies *fixP as appropriate.  In the case
  3603.            * of a 'calls', no further work is required, and *fixP has been
  3604.            * set up to make the rest of the code below a no-op.
  3605.            */
  3606.           reloc_callj (fixP);
  3607. #endif /* TC_I960 */
  3608.  
  3609.           add_number += S_GET_VALUE (add_symbolP);
  3610.           add_number -= md_pcrel_from (fixP);
  3611. #if defined (TC_I386) || defined (TE_LYNX)
  3612.           /* On the 386 we must adjust by the segment
  3613.          vaddr as well.  Ian Taylor.  */
  3614.           add_number -= segP->scnhdr.s_vaddr;
  3615. #endif
  3616.           pcrel = 0;    /* Lie. Don't want further pcrel processing. */
  3617.           fixP->fx_addsy = NULL;
  3618.           fixP->fx_done = 1;
  3619.         }
  3620.       else
  3621.         {
  3622.           switch (add_symbol_segment)
  3623.         {
  3624.         case absolute_section:
  3625. #ifdef TC_I960
  3626.           reloc_callj (fixP);    /* See comment about reloc_callj() above*/
  3627. #endif /* TC_I960 */
  3628.           add_number += S_GET_VALUE (add_symbolP);
  3629.           fixP->fx_addsy = NULL;
  3630.           fixP->fx_done = 1;
  3631.           add_symbolP = NULL;
  3632.           break;
  3633.         default:
  3634.  
  3635. #ifdef TC_A29K
  3636.           /* This really should be handled in the linker, but
  3637.              backward compatibility forbids.  */
  3638.           add_number += S_GET_VALUE (add_symbolP);
  3639. #else
  3640.           add_number += S_GET_VALUE (add_symbolP) +
  3641.             segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
  3642. #endif
  3643.           break;
  3644.  
  3645.         case SEG_UNKNOWN:
  3646. #ifdef TC_I960
  3647.           if ((int) fixP->fx_bit_fixP == 13)
  3648.             {
  3649.               /* This is a COBR instruction.  They have only a
  3650.                * 13-bit displacement and are only to be used
  3651.                * for local branches: flag as error, don't generate
  3652.                * relocation.
  3653.                */
  3654.               as_bad_where (fixP->fx_file, fixP->fx_line,
  3655.                     "can't use COBR format with external label");
  3656.               fixP->fx_addsy = NULL;
  3657.               fixP->fx_done = 1;
  3658.               continue;
  3659.             }        /* COBR */
  3660. #endif /* TC_I960 */
  3661. #if defined (TC_I386) || defined (TE_LYNX)
  3662.           /* 386 COFF uses a peculiar format in
  3663.              which the value of a common symbol is
  3664.              stored in the .text segment (I've
  3665.              checked this on SVR3.2 and SCO 3.2.2)
  3666.              Ian Taylor <ian@cygnus.com>.  */
  3667.           if (S_IS_COMMON (add_symbolP))
  3668.             add_number += S_GET_VALUE (add_symbolP);
  3669. #endif
  3670.           break;
  3671.  
  3672.  
  3673.         }        /* switch on symbol seg */
  3674.         }            /* if not in local seg */
  3675.     }            /* if there was a + symbol */
  3676.  
  3677.       if (pcrel)
  3678.     {
  3679. #ifndef TC_M88K
  3680.       /* This adjustment is not correct on the m88k, for which the
  3681.          linker does all the computation.  */
  3682.       add_number -= md_pcrel_from (fixP);
  3683. #endif
  3684.       if (add_symbolP == 0)
  3685.         {
  3686.           fixP->fx_addsy = &abs_symbol;
  3687.         }            /* if there's an add_symbol */
  3688. #if defined (TC_I386) || defined (TE_LYNX)
  3689.       /* On the 386 we must adjust by the segment vaddr
  3690.          as well.  Ian Taylor.  */
  3691.       add_number -= segP->scnhdr.s_vaddr;
  3692. #endif
  3693.     }            /* if pcrel */
  3694.  
  3695.       if (!fixP->fx_bit_fixP)
  3696.     {
  3697. #ifndef TC_M88K
  3698.       /* The m88k uses the offset field of the reloc to get around
  3699.          this problem.  */
  3700.       if ((size == 1 &&
  3701.       (add_number & ~0xFF) && ((add_number & ~0xFF) != (-1 & ~0xFF))) ||
  3702.           (size == 2 &&
  3703.            (add_number & ~0xFFFF) && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF))))
  3704.         {
  3705.           as_bad_where (fixP->fx_file, fixP->fx_line,
  3706.                 "Value of %ld too large for field of %d bytes at 0x%lx",
  3707.                 (long) add_number, size,
  3708.                 (unsigned long) (fragP->fr_address + where));
  3709.         }            /* generic error checking */
  3710. #endif
  3711. #ifdef WARN_SIGNED_OVERFLOW_WORD
  3712.       /* Warn if a .word value is too large when treated as
  3713.          a signed number.  We already know it is not too
  3714.          negative.  This is to catch over-large switches
  3715.          generated by gcc on the 68k.  */
  3716.       if (!flag_signed_overflow_ok
  3717.           && size == 2
  3718.           && add_number > 0x7fff)
  3719.         as_bad_where (fixP->fx_file, fixP->fx_line,
  3720.               "Signed .word overflow; switch may be too large; %ld at 0x%lx",
  3721.               (long) add_number,
  3722.               (unsigned long) (fragP->fr_address + where));
  3723. #endif
  3724.     }            /* not a bit fix */
  3725.       /* once this fix has been applied, we don't have to output anything
  3726.        nothing more need be done -*/
  3727.       md_apply_fix (fixP, add_number);
  3728.     }                /* For each fixS in this segment. */
  3729. }                /* fixup_segment() */
  3730.  
  3731. #endif
  3732.  
  3733. /* The first entry in a .stab section is special.  */
  3734.  
  3735. void
  3736. obj_coff_init_stab_section (seg)
  3737.      segT seg;
  3738. {
  3739.   char *file;
  3740.   char *p;
  3741.   char *stabstr_name;
  3742.   unsigned int stroff;
  3743.  
  3744.   /* Make space for this first symbol. */
  3745.   p = frag_more (12);
  3746.   /* Zero it out. */
  3747.   memset (p, 0, 12);
  3748.   as_where (&file, (unsigned int *) NULL);
  3749.   stabstr_name = (char *) alloca (strlen (segment_info[seg].scnhdr.s_name) + 4);
  3750.   strcpy (stabstr_name, segment_info[seg].scnhdr.s_name);
  3751.   strcat (stabstr_name, "str");
  3752.   stroff = get_stab_string_offset (file, stabstr_name);
  3753.   know (stroff == 1);
  3754.   md_number_to_chars (p, stroff, 4);
  3755. }
  3756.  
  3757. /* Fill in the counts in the first entry in a .stab section.  */
  3758.  
  3759. static void
  3760. adjust_stab_section(abfd, seg)
  3761.      bfd *abfd;
  3762.      segT seg;
  3763. {
  3764.   segT stabstrseg = SEG_UNKNOWN;
  3765.   char *secname, *name, *name2;
  3766.   char *p = NULL;
  3767.   int i, strsz = 0, nsyms;
  3768.   fragS *frag = segment_info[seg].frchainP->frch_root;
  3769.  
  3770.   /* Look for the associated string table section. */
  3771.  
  3772.   secname = segment_info[seg].scnhdr.s_name;
  3773.   name = (char *) alloca (strlen (secname) + 4);
  3774.   strcpy (name, secname);
  3775.   strcat (name, "str");
  3776.  
  3777.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  3778.     {
  3779.       name2 = segment_info[i].scnhdr.s_name;
  3780.       if (name2 != NULL && strncmp(name2, name, 8) == 0)
  3781.     {
  3782.       stabstrseg = i;
  3783.       break;
  3784.     }
  3785.     }
  3786.  
  3787.   /* If we found the section, get its size. */
  3788.   if (stabstrseg != SEG_UNKNOWN)
  3789.     strsz = size_section (abfd, stabstrseg);
  3790.  
  3791.   nsyms = size_section (abfd, seg) / 12 - 1;
  3792.  
  3793.   /* Look for the first frag of sufficient size for the initial stab
  3794.      symbol, and collect a pointer to it. */
  3795.   while (frag && frag->fr_fix < 12)
  3796.     frag = frag->fr_next;
  3797.   assert (frag != 0);
  3798.   p = frag->fr_literal;
  3799.   assert (p != 0);
  3800.  
  3801.   /* Write in the number of stab symbols and the size of the string
  3802.      table. */
  3803.   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
  3804.   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
  3805. }
  3806.  
  3807. #endif /* not BFD_ASSEMBLER */
  3808.  
  3809. const pseudo_typeS obj_pseudo_table[] =
  3810. {
  3811.   {"def", obj_coff_def, 0},
  3812.   {"dim", obj_coff_dim, 0},
  3813.   {"endef", obj_coff_endef, 0},
  3814.   {"line", obj_coff_line, 0},
  3815.   {"ln", obj_coff_ln, 0},
  3816.   {"appline", obj_coff_ln, 1},
  3817.   {"scl", obj_coff_scl, 0},
  3818.   {"size", obj_coff_size, 0},
  3819.   {"tag", obj_coff_tag, 0},
  3820.   {"type", obj_coff_type, 0},
  3821.   {"val", obj_coff_val, 0},
  3822.   {"section", obj_coff_section, 0},
  3823. #ifndef BFD_ASSEMBLER
  3824.   {"use", obj_coff_section, 0},
  3825.   {"sect", obj_coff_section, 0},
  3826.   {"text", obj_coff_text, 0},
  3827.   {"data", obj_coff_data, 0},
  3828.   {"bss", obj_coff_bss, 0},
  3829.   {"lcomm", obj_coff_lcomm, 0},
  3830.   {"ident", obj_coff_ident, 0},
  3831. #else
  3832.   {"optim", s_ignore, 0},    /* For sun386i cc (?) */
  3833.   {"ident", s_ignore, 0},    /* we don't yet handle this. */
  3834. #endif
  3835.   {"ABORT", s_abort, 0},
  3836. #ifdef TC_M88K
  3837.   /* The m88k uses sdef instead of def.  */
  3838.   {"sdef", obj_coff_def, 0},
  3839. #endif
  3840.   {NULL}            /* end sentinel */
  3841. };                /* obj_pseudo_table */
  3842.